What is Megaphone?

What is Megaphone?
The Megaphone project is about enhancing open source chat software. Specifically, the goal is to allow ejabberd to support 1,000,000 simultaneous users. See The Plan page for more details on how I plan to solve this problem. See the About this Blog page for more details on why I created this blog.

Sunday, January 15, 2012

Simulating Connections

Previously...
  • I switched ECM over to using a straight nodejs TCP server.
  • I learned about parsing HTTP packets from a buffer.
  • I resolved to use a single process to respond to ejabberd_http.

The primary issue I have with ejabberd_http is this: what happens if the call comes in to megaphone_socket for data on a connection, and there is no data available?

Normally, with a separate process, the answer is relatively simple: you just call receive and wait for someone else to hand you some data.  My previous decision regarding processes --- that I should create as few of them as possible --- complicates matters.


Trying to understand this, I came up with the following event sequence diagrams:

data is available at the time of call


ejabberd        megaphone_      megaphone       megaphone_      gen_tcp
http            socket                          tcp
|               |               |               |               |
|               |               |               recv(Socket)    |
|               |               |               --------------->|
|               |               |               (data)          |
|               |               |               |<---------------
|               |               |data_received(data)            |
|               |               |<---------------               |
|               |               |               |               |
<megaphone parses out the connection ID>
<Nobody is registered to receive updates about this connection so no
 messages go out>
|               |               |               |               |
start(connection ID)            |               |               |
|<-------------------------------               |               |
recv (connection ID)            |               |               |
--------------->|               |               |               |
|               get_data (connection ID)        |               |
|               --------------->|               |               |
|               |               |               |               |
< megaphone gets the data from the dictionary of connection data >
|               |               |               |               |
|               (return (data)) |               |               |
|               |<---------------               |               |
|{ok, http_request }            |               |               |
|<---------------               |               |               |
|               |               |               |               |


data is not available at the time of call


ejabberd        megaphone_      megaphone       megaphone_      gen_tcp
http            socket                          tcp
|               |               |               |               |
|               |               |               recv(Socket)    |
|               |               |               --------------->|
|               |               |               (data)          |
|               |               |               |<---------------
|               |               |data_received(data)            |
|               |               |<---------------               |
|               |               |               recv(Socket)    |
|               |               |               --------------->|
|               |               |               |               |
<megaphone parses out the connection ID>
<Nobody is registered to receive updates about this connection so no
 messages go out>
|               |               |               |               |
start(connection ID)            |               |               |
|<-------------------------------               |               |
|               |               |               |               |
...
|               |               |               |               |
recv (connection ID)            |               |               |
--------------->|               |               |               |
|               get_data (connection ID)        |               |
|               --------------->|               |               |
|               |               |               |               |
< megaphone notes that there is no data for the provided connection ID >
|               |               |               |               |
|               (return, no data)               |               |
|               |<---------------               |               |
|               receive         |               |               |
|               -------\        |               |               |
|               |<-----/        |               |               |
|               |               |               |               |
< the ejabberd_http process waits on the call the recv, which in 
  turn, waits on the call to receive>
...
|               |               |               |               |
|               |               |               (data)          |
|               |               |               |<---------------
|               |               |data           |               |
|               |               |<---------------               |
|               |               |               |               |
< megaphone notes that this is for a connection that has a registered 
  listener >
|               |               |               |               |
|               data (data)     |               |               |
|               |<---------------               |               |
|{ok, http_request }            |               |               |
|<---------------               |               |               |
|               |               |               |               |


This requires the creation of a new process: megaphone_tcp.  This is something that sits around and listens for new TCP data to become available.  It also requires the creation of the megaphone process: the basic purpose of that actor is to synchronize access to connection data that is shared by all the ejabberd_http processes that need data.

The whole notion of managing subscriptions to data for each connection may or may not actually be necessary.  It really depends on how ejabberd_http expects to receive data: if it wants to receive new packets via calling receive, then something like a separate megaphone process is needed because ejabberd_http will end up calling megaphone_socket to get each packet.

A separate process is not needed if ejabberd_http processes one posting and then terminates the associated erlang process.  This is because ejabberd_http will always be started in response to megaphone receiving a new, complete packet.  megaphone should always have the data that ejabberd_http wants.

So the next steps are to create the megaphone and megaphone_tcp processes.

No comments:

Post a Comment