I already played around with Elixir in order to implement an IRC server. Actually I restructured the application twice to make it work, but still it’s far from beeing useful. So once again I am getting back to the drawing board in an attempt to get it right. This time, though, I blog about what I did or am about to do.

Before I start implementing I need to make up my mind about how the application(s) will be structured. Let’s start with identifying the movable parts of the application (I concentrate on serving clients for now).

Moveable Parts

Application: Server (IRC)

Obviously I am going to implement a server. The server will listen on the configured interface (address and port) and accept and spawn a new process for each incoming connexion.

Module: Connexion -> (IRC.Connexion)

Each user, service, server connexion (to or from my server) and/or channel is represented with an individual Connexion process. This is probably where the main logic will probably be implemented. Once a connexion is registered (by means of the IRC protocol) the connexion will register itself at the Registry.

Application: Registry -> (IRC.Registry)

In order to ensure no nickname and/or channel gets used twice I need some sort of registry. Here a some for of unique identification (full user identification in form of nickname!username@host for users, services and servers or a channel name for channels) is mapped to a Connexion. Since in case of servers one connexion can represent mulitple users, one Connexion can be the value of multiple keys (full user ids). On the other side a Channel can represent multiple Connexions.

Module: Parser (IRC.Parser)

The IRC protocol specifies a simple, well defined, protocol to communication between two end-points. I will implement a parser in order to easily transfer incoming messages into structures and vice versa.

Plan of Attack

As with my previous tests, this sounds correct, but I will see if this works out the way it should. Nevertheless I now need a plan of attack to write these applications and modules. Let’s identifiy the hierachy.

Server uses the Connexion Registry to create connexions.

The Registry creates and monitors a Connexion process for connected clients. Also the Registry creates and monitors Channels. When a Connexion dies, the Registry removes it from all the Channels it was in. The Registry most likely will also need to use the Parser to process user names, etc.

Connexion accesses the Registry to check for nickname and to register itself under a unique name (or multiple names in case the connexion is a server connexion). Connexion also uses Channel and most likely the Parser.

A Channel is kind of a special Connexion in that it does not represent a single connexion to a server, service or user, but instead represent multiple Connexions.

    Server ---+---> Connexion ---+---> Registry ---+
                                 |                 |
                                 +---> Parser <----+

Therefore I will start with the Parser, the write the Registry, implement the Connexion and finish up with the Server. I mostly likely will not completely finish one module/application before moving to the next, but implement the basics so I can wire them together and have a (albeit limited) working implementation.