<div dir='auto'>I meant to test your state machine, obviously. </div><div class="gmail_extra"><br><div class="gmail_quote">Le 25 janv. 2017 11:11 AM, Éric Pailleau <eric.pailleau@wanadoo.fr> a écrit :<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Hi,<div dir="auto">For the telnet part, see http://erlang.org/doc/man/ct_telnet.html</div><div dir="auto">In particular expect function will save your day.</div><div dir="auto">Regard </div></div><div><br /><div class="elided-text">Le 24 janv. 2017 6:24 PM, Thom Cherryhomes <thom.cherryhomes@gmail.com> a écrit :<br /><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thanks so much for replying!<div><br /></div><div>I've definitely got a ton of thinking ahead, but your comments have verified what little I have been able to figure out, thus far.</div><div><br /></div><div>The irony here is that I think the telnet part of the system will be the most complex, as it has to convey a highly stateful and interactive graph... a web frontend, or a json API for a thick client will be infinitely easier to deal with when the time comes...heheh...</div><div><br /></div><div>I'll try to do a pattern where each part of the BBS is its own application, with a well defined protocol, that a proxy links to and requests a new process for...</div><div><br /></div><div>...as well as remove gen_statem from the client, and turn it into a gen_server, leaving gen_statem for the "other" side... </div><div><br /></div><div>To tell a bit more about what I'm writing:</div><div><br /></div><div>This is a sort of 21st century equivalent to a BBS system, think a BBS that has learned the lessons from today's social networks, and provides multiple front-ends for computers vintage and new alike, where:</div><div><br /></div><div>* frontends for telnet</div><div> * ASCII, ANSI, PETSCII, ATASCII, etc..etc.</div><div>* web frontend</div><div>* JSON API for thick clients</div><div>* Users create their own boards, public, or private</div><div>* Ability to utilize distributed model to replicate boards to other BBSes</div><div>* Chat</div><div>* Games</div><div><br /></div><div>Yeah, it may seem quaint, but i've wanted to write a board of my own for about 25 years, but never found the time. </div><div><br /></div><div>The combination of learning Erlang, and seeing what it could provide to facilitate this idea, is what has spurred me into finally implementing it. </div><div><br /></div><div>I do not intend to make any money off of it, and will release it GPL, but I want to make an actual, real example of a _LARGE_ Erlang system, so people can see how one would be put together.</div><div><br /></div><div>-Thom</div><div><br /><div><div dir="ltr">On Tue, Jan 24, 2017 at 5:48 AM Jesper Louis Andersen <<a href="mailto:jesper.louis.andersen@gmail.com">jesper.louis.andersen@gmail.com</a>> wrote:<br /></div><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div>Here are some thoughts off-hand. They are not too fleshed out.<br /><br /></div>* I'd definitely run things via Ranch if possible. Some of the subtler things in and around reconnect accept pools and so on happens to be solved well by Loic in Ranch.<br /><br /></div>* It may be possible to generalize buffer handling from the user. Consider a function handle(Data, BufferState) -> {Cmds, UpdatedBufferState}, where Cmds is a list of the commands the user entered.<br /><br /></div>* Most modules in a BBS probably runs in a Request -> Reply fashion. You send a command to the module and it replies with a new display state you send to the BBS client. Since each module will keep its own state, you can stuff that into a process.<br /><br /></div>* Modules may have their own state. They may also have BBS-global state which enables communication between clients. Say you have a forum module. It will have a forum_backend in which you store the actual posts in the forum. When a client requests forum access, you spawn a helper which runs the Request/Reply pattern proxying the data in the backend to the client.<br /><br /></div>* gen_statem is probably most useful in modules, and not so much in the client itself, unless the interactions are complex and there are certain things which can only happen in some limited states, etc.<br /><br /></div>* Be aggressive and link everything or use monitors. That way, you can easily handle errors in parts of the system without taking it all down. Also, you can probably handle a hangup by simply terminating the client process and then have modules handle a 'DOWN' message and clean up.<br /><br /></div>* Old BBS'es did not really have it that much, but you could write a general command parser and then supply parsed terms to modules. This becomes yet another state machine, but it often kept inside the client process:<br /><br /></div>-record(state, {<!-- --><br /></div> buffer_state :: buffer_state(),<br /></div> parser_state :: parser_state(),<br /></div> socket :: inet:socket(),<br /> ...<br />}).<br /><br /></div>* A common beginners mistake is to want to process everything en masse. The rule of thumb is to create a process for each truly concurrent activity in the system. With that in mind, it may be that module state should not by in a proxy process, as above, but rather be embedded directly in the client. The forum_backend is truly concurrent however and warrants its own process.<br /><br /></div>* The counterpoint to the last remark: don't be afraid to use a process to isolate parts of your system and keep complexity down. Juggling many states in one process at the same time means you have to handle every complex cross-interaction between them. If you push something to its own process, then chances are there are less cross-talk and thus a system which is easier to understand and handle.<br /><br /></div>* Finally: rather than focusing on the "behaviour", focus on the interaction protocol. When you talk HTTP, you don't do that by inheriting a HTTP-class. You do that by speaking the protocol. This is powerful because you *don't* know the internal implementation of the HTTP server. REST was only possible in the first place because HTTP was a protocol. In a BBS, focus on the module interaction protocol. You don't care for the internal implementation, but rather how you talk to it. Once established, it may be that 80% of the modules can implemented via a generic callback framework, as is the case for the gen_server (where the protocol is OTP). But there are always 20% which are not fitting in, and you want that to be possible as well.<br /><br /></div>Feel free to follow up :)<br /><br /></div><br /><div></div><div><div dir="ltr">On Tue, Jan 24, 2017 at 6:02 AM Thom Cherryhomes <<a href="mailto:thom.cherryhomes@gmail.com">thom.cherryhomes@gmail.com</a>> wrote:<br /></div></div><div><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Would you, for example, build the ranch protocol as simple as possible, and link the other application servers, as needed, with a common protocol?</div><div dir="ltr"><div><br /></div><div>-Thom</div></div><br /><div><div dir="ltr">On Sun, Jan 22, 2017 at 2:56 PM Thom Cherryhomes <<a href="mailto:thom.cherryhomes@gmail.com">thom.cherryhomes@gmail.com</a>> wrote:<br /></div><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">
<p style="margin-bottom:0in;line-height:100%">Hello, everyone.
This is my first post to the list.
</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">I’m a long time
swiss army knife of a software and hardware engineer who has started
to pick up Erlang, because I believe it and languages like it to be
the future of software development.</p>
<p style="margin-bottom:0in;line-height:100%">With that said, I am
working on a personal project of mine that I have wanted to complete,
a 21<sup>st</sup> century version of a BBS system, and I believe
Erlang and OTP are a good language and toolkit to write it in.</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">Code is being
dropped here: <a href="http://github.com/tschak909/nakbbs">http://github.com/tschak909/nakbbs</a></p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">I am experimenting
with both Ranch and just using gen_tcp with my own socket pools, but
I do have some design questions.</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">The telnet ports
need to present a definite series of states, broken up into seperate
pieces:</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">I have definite
common events that can be stretched across multiple use cases:</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">* Display</p>
<p style="margin-bottom:0in;line-height:100%">* Wait for line of
input</p>
<p style="margin-bottom:0in;line-height:100%">* Wait for character
input</p>
<p style="margin-bottom:0in;line-height:100%">* branch to another
menu</p>
<p style="margin-bottom:0in;line-height:100%">* hang up</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;border-top:none;border-bottom:1px solid rgb( 0 , 0 , 0 );border-left:none;border-right:none;padding:0in 0in 0.03in;line-height:100%">
But there will also be definite sections of the system, which could
be thought of as states:</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">* Authentication</p>
<p style="margin-bottom:0in;line-height:100%">* Message Browser</p>
<p style="margin-bottom:0in;line-height:100%">* Message Editor</p>
<p style="margin-bottom:0in;line-height:100%">* Various Games</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">etc.</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">and I’m trying to
think of an appropriate architectural pattern that will avoid me
basically having to cram every conceivable state as a sort of
hierarchy of tuples into a single gen_statem module. How can I
approach this in a nice abstract and extensible manner, that I could
for example push into a Behaviour and subsequently utilize for
different terminal types? It would be nice to split up the different
parts of the system into applications that would essentially be
called from well defined APIs…</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">I’m just trying to
figure this all out, and would love a semblence of direction so I can
do the proper research and deeply understand what I need to learn.</p></div><div dir="ltr">
<p style="margin-bottom:0in;line-height:100%"><br />
</p>
<p style="margin-bottom:0in;line-height:100%">-Thom</p>
<p style="margin-bottom:0in;line-height:100%"><br />
</p></div></blockquote></div></blockquote></div><div><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex">
_______________________________________________<br />
erlang-questions mailing list<br />
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br />
<a href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a><br />
</blockquote></div>
</blockquote></div></div></div>
</blockquote></div><br /></div></blockquote></div><br></div>