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.

Thursday, January 26, 2012

megaphone III: Getting Data

Previously...
  • I did some more planning for the megaphone module.
  • I created the main loop for the megaphone module.
  • I coded up the interface functions for the megaphone module.

The first part that I'm going to talk about is the function that is used when ejabberd wants to get new data from a connection.  The data itself is stored in an erlang dictionary as a list of results.  The table is indexed via connection ID.  Here is the code for the function:

get_data(State, From, ConnectionID) ->
    Table = State#megaphone_main_state.connectionToResults,
    case dict:is_key(ConnectionID, Table) of
        false ->
            State;

        true ->
            case dict:fetch(ConnectionID, Table) of
                [ Head | Rest ] ->
                    From ! { ok, Head },
                    Table2 = dict:store(ConnectionID, Rest, Table),
                    State#megaphone_main_state{connectionToResults = Table2};

                [] ->
                    Waiters = State#megaphone_main_state.waiters,
                    Waiters2 = dict:store(ConnectionID, From, Waiters),
                    State#megaphone_main_state{waiters = Waiters2}
            end
    end.


The dictionary module reacts violently if you ask for a key that is not present, hence the need for a call to dict:is_key before trying to access the data.  erlang is a little strange in the way it does if-then-else statements in that you are restricted in the conditional statement.  A case statement does not have this restriction, hence I often find myself using a case where I would normally use an if in a language like Java.  

Basically I'm too lazy to check to see whether an if statement would do, so I usually use case.

Sigh.

Anyhow, the contents of the table are lists of results that I get out of erlang:decode_packet.  If some data exists for the requested ConnectionID, then the function responds back to the requester with the data.  If the list is empty of results then the client needs to block waiting for data to arrive.  

Waiting is implemented by creating a callback table: when the data arrives the waiting process is sent a message with the data.  But the megaphone process needs some way of figuring out who to send messages to: hence the callback table.

I suppose I could use the callback table to also send annoying messages and musak akin to what human beings have to put with while on hold but I am basically a kindly person.

Next time, the code for when data comes in to the megaphone system.

No comments:

Post a Comment