libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] Stuck Single Threaded


From: Kenneth Mastro
Subject: Re: [libmicrohttpd] Stuck Single Threaded
Date: Wed, 7 May 2014 11:49:47 -0400

Date: Wed, 07 May 2014 14:24:40 +0200
From: Christian Grothoff <address@hidden>
To: address@hidden
Subject: Re: [libmicrohttpd] Stuck Single Threaded
Message-ID: <address@hidden>
Content-Type: text/plain; charset="utf-8"

On 05/05/2014 10:10 PM, Kenneth Mastro wrote:
> First, great library!  Thanks for creating it!
>
> Using microhttpd, I created a reasonably well performing webserver for
> an embedded system I'm working on.  Everything has been going well, but
> I'm stuck on something.
>
> I've been trying to add a 'Comet' feature to the library where
> long-polling can be done.  In short, during the default URI handler
> callback (provided as args 5&6 to the start_daemon setup call), I
> ultimately 'wait' for the server to produce a message to send back to
> the client.  I.e., the long-poll.  If there are no messages after a
> while (e.g., a minute), I return an empty message back to the client and
> force it to ask again.
>
> The problem I'm having is that this seems to prevent the daemon from
> processing any other incoming connections - regardless of my threading
> model.  I had assumed that 'select + thread pool' or 'one thread per
> connection' would allow what I'm doing to work, but it doesn't - it just
> sits and waits for the long-poll to time out (or send a valid message)
> before servicing the next client request.
>
> This isn't the behavior I expected - particularly for the 'one thread
> per connection' mode.
>
> Should I be doing this a different way?  I don't quite see how, but is
> this main callback the wrong place to do something like this?  Is my
> webserver structurally flawed in that I generate the content in that
> callback thread, in general?
>
> As a side note, I haven't played with the 'suspend/resume' option, yet -
> but it seems like that shouldn't be necessary (or valid/appropriate) for
> 'one thread per connection' mode.
>
> In short - how should I use the library to hold onto a request for an
> extended period of time as it prepares an answer while still allowing it
> to service other requests?

That is usually not an issue; however, if you set a limit on the
number of parallel connections MHD is allowed to serve, then 'holding'
one request may prevent MHD from accepting additional requests.  So
check that you didn't limit the requests (overall) or by IP address.

Note that you can do long polling even with the other threading modes,
but those might be more complicated to use (you'll need to use stuff
like MHD_connection_suspend and returning '0' from the content reader
callback.

As to the structure of your webserver, MHD deliberately offers you
various ways to generate the reply and organize your web server;
using the thread-per-connection method is not the most scalable
method, but not per-se bad --- I don't know your application, so
I cannot say if your webserver is 'flawed'.  What I can say is that
yes, you should be able to do a 'Comet' feature this way with MHD in
principle.


I hope this helps!

Happy hacking!

Christian

Thanks, Christian.  I was able to get long-polling working.  The problem was in my testing methodology (see my message from a couple hours ago).  MHD is indeed flexible with regards to request processing - that's one of the reasons I thought I was doing something wrong. :)

Another question, though, since you brought it up.  My preferred threading mode is select (or maybe epoll, since I'm on Linux - haven't tried it yet) with a thread-pool.  My past development experience leads me to assume that is the best combination of efficiency and performance, in general.  I haven't seen any problems with doing it this way, but I'm not using the suspend/resume stuff.

However - Your message implies there could be complications if I go that route.  Should I use the built-in suspend/resume stuff even if I'm using a thread pool, or is it ok to just pause one of the MHD threads for the long-poll?  Seems like it should be fine unless there's something funky about those threads or their management.

I'm sure I could save some memory and task switching by suspending/resuming, but I don't think it's worth the extra complication if there isn't some inherent problem with the way I'm doing it.

I don't have to worry much about the number of simultaneous users - I'm putting a cap on it at 10 users, with a maximum of 1 long-poll each, and I've set aside 20 threads in the pool.  Should be more than enough.  Memory use is not a big concern as long as it's not obscene.


Thanks again for such a great library!

Ken


reply via email to

[Prev in Thread] Current Thread [Next in Thread]