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.

Monday, January 30, 2012

megaphone VI: Waiting for Data

Previously...
  • I coded up the get_data function
  • I coded up the put_data function
  • I coded up the put_data function...again

While coding up the stuff to notify the waiter, I noticed that the code to get the waiter was using the wrong hash table.  Mind you, I knew that when I was making that post!  It was all a test to see if any alert readers would catch that problem.  

But nobody did.

I hope you have all learned an important lesson from this, and it is not that I am a spastic programmer.  Who makes tons of mistakes.  Yeah, well, anyways, here is the revised version of remove_waiter:

remove_waiter(ConnectionID, State) ->
    Table = State#megaphone_main_state.waiters,
    case dict:is_key(ConnectionID, Table) of
        false -> { undefined, State};
        true ->
            { Waiter, NewTable } = case dict:fetch(ConnectionID, Table) of
                [ PID | Rest ] ->
                    UpdatedTable = dict:store(ConnectionID, Rest, Table),
                    { PID, UpdatedTable};

                [] ->
                    UpdatedTable = dict:erase(ConnectionID, Table),
                    { undefined, UpdatedTable}
            end,
            NewState = State#megaphone_main_state{waiters = NewTable},
            { Waiter, NewState }
    end.

And here is the code for notify_waiter:

notify_waiter(Waiter, ConnectionID, State) ->
    Table = State#megaphone_main_state.connectionToResults,
    case dict:is_key(ConnectionID, Table) of
        false ->
            ?ERROR_MSG("could not find data that we were just asked to deliver!  Connection ID: ~p", [ConnectionID]),
            State;

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

                [] ->
                    ?ERROR_MSG("Data we were supposed to deliver is missing for connection ID: ~p", [ConnectionID]),
                    NewTable = dict:erase(ConnectionID, Table),
                    State#megaphone_main_state{connectionToResults = NewTable}
            end
    end.

For next time, parsing HTTP packets.

No comments:

Post a Comment