<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 22, 2016 at 4:06 AM, Matthew Shapiro <span dir="ltr"><<a href="mailto:me@mshapiro.net" target="_blank">me@mshapiro.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I am now at the point where I want to test some of this knowledge out, and I thought a good idea was to create a (basic) IRC server (as I've written them in the past in other languages, and it seemed like a good use case for Erlang).</blockquote></div><br></div><div class="gmail_extra">Here is how I would do it:<br><br></div><div class="gmail_extra">* There is no reason to run your own acceptor pool. Every client connecting runs behind the `ranch` acceptor pool.<br><br></div><div class="gmail_extra">* The thing that happens concurrently in an IRC server are the connecting clients. There is relatively little need for a channel to act on behalf of itself, so one may look at a solution where a channel is just a list of members, handled by a general manager of channel lists in ETS. Posting a message to a channel is simply looking up interested parties, and sending the message to all of them. OTOH, having a process per channel could be helpful in order to proxy messages via the channel process: send to the chan process, and have it forward to the recipients. Which is best depends is not a priori clear to me, but when I did this years ago, I managed to do this without channel processes.<br><br></div><div class="gmail_extra">* Consider managing the registry of Pids through either the `gproc` or the `syn` frameworks. This avoids you having to redo most of the nasty parts of registry and you can avoid the problems of using atoms only as in the local registry.<br><br></div><div class="gmail_extra">* If you want your server to run as a cluster, you will have to think about the problem of a netsplit inside the cluster and what guarantees you want to have.<br><br></div><div class="gmail_extra">This leaves your supervisor tree in one of two forms: Either the top-level supervisor runs a single channel manager process worker, or it runs a simple_one_for_one pool of channels together with a manager for creating/removing channels, if you deem it necessary to keep a process tracking each channel.<br clear="all"></div><div class="gmail_extra"><br></div><div class="gmail_extra">In general, I would avoid solutions where you "hand off" state between processes as if they were sitting in a pipeline. It is often better to make the process itself run as an independent system. Joe said "An Erlang web server runs 2 million webservers, each serving one request." In this case, you could argue you want to run a couple thousand IRC servers, each serving one channel, and a couple thousand connection proxies, each serving one TCP connection, connecting to multiple such channels. A connection proxy then has the task of transforming the outside IRC protocol into nice symbolic Erlang terms band and forth. And the Channel servers are tasked with handling pub/sub between the processes, as well as ownership management of the channels in question.<br><br></div><div class="gmail_extra">The trick is to get events/messages to flow between the connection processes such that the emergent behavior of a wild IRCd suddenly appears :)<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">-- <br><div class="gmail_signature">J.</div>
</div></div>