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, March 8, 2012

Home Sweet Home

Previously...
  • I determined that megaphone needed to listen for new connections.
  • I came to a conclusion regarding how to watch for new connections.
  • I discovered a correction for a previous correction.

Before I start blathering on about how my latest blunder I want to give a shout out to the good ole USA!  This has nothing to do with the fact that a recent surge (9 hits) seem to have put the ole US of A at the top of my traffic sources, but also because it is my my home sweet home and despite some truly stupid policies that have come out through the years this is the country that I would rather be my home than any other.  In addition the USA made the internet popular, came up with Star Wars and the Egg McMuffin.  All great achievements.

Anyhow, I'm still slogging through ejabberd code, trying  to figure out just how I can introduce a new connection from megaphone to the ejabberd establishment.  Unfortunately, the code is hard for me to understand so I still find myself flailing about try to figure out what function should be called.  

For example, it might appear that calling ejabberd_http:


start(SockData, Opts) ->

    supervisor:start_child(ejabberd_http_sup, [SockData, Opts]).

But the a few layers down I find this

 {SockMod1, Socket1} =
    if
        TLSEnabled ->
        inet:setopts(Socket, [{recbuf, 8192}]),
        {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts),
        {tls, TLSSocket};
Which could cause problems if the request is for a TLS conversation.  The calls to inet:setops will not work given that I wont be passing the socket around, instead I will be using a connection ID.

Another possibility is receive_header:


receive_headers(State) ->

    SockMod = State#state.sockmod,
    Socket = State#state.socket,
    Data = SockMod:recv(Socket, 0, 300000),
    case State#state.sockmod of
    gen_tcp ->
        NewState = process_header(State, Data),
        case NewState#state.end_of_request of
        true ->
            ok;
        _ ->
            receive_headers(NewState)
        end;
    _ ->
        case Data of
        {ok, Binary} ->
            {Request, Trail} = parse_request(
                     State,
                     State#state.trail ++ binary_to_list(Binary)),
            State1 = State#state{trail = Trail},
            NewState = lists:foldl(
                 fun(D, S) ->
                    case S#state.end_of_request of
                        true ->
                        S;
                        _ ->
                        process_header(S, D)
                    end
                 end, State1, Request),
            case NewState#state.end_of_request of
            true ->
                ok;
            _ ->
                receive_headers(NewState)
            end;
        _ ->
            ok
        end
    end.

I guess that this thing is trying to receive the headers from the request a la. erlang:decode_packet.  I suppose I could change the statement

    gen_tcp ->
        NewState = process_header(State, Data),

to something like 

    gen_tcp || megaphone ->
        NewState = process_header(State, Data),

And then hope for the best.  According to blog search I haven't talked about process_header before, so hopefully I'm not running around in circles. The big problem is that I would have to deal with setting up a synthetic state value when I call receive_headers.  

Next time: more analysis (sigh)

No comments:

Post a Comment