[Top][All Lists]

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

[libmicrohttpd] Stuck Single Threaded

From: Kenneth Mastro
Subject: [libmicrohttpd] Stuck Single Threaded
Date: Wed, 7 May 2014 08:48:04 -0400

>>2014-05-05 22:10 GMT+02:00 Kenneth Mastro <address@hidden>:
>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?
>I'm using version 0.9.34 of microhttpd on Linux.
>Thanks much,

>Hi Kenneth,
>I'm just a user of the library like you so no developer here, but I am using it as you'd like to in my project, and it works great, tons of parallel requests being handled and no issue. I use the "one thread per connection" flag, for long polls I wait until I have data to provide (or reply when a timeout fires) and I do generate all the content in the callback thread, so I'm not sure what you may be doing wrong. Unlike you, I'm using poll instead of select, but I seem to recall testing select as well just fine.
>If it can help, this is where I use the library:
>just look for janus_ws_handler which is the request callback. Whenever a long poll is involved (a GET) a separate function, janus_ws_notifier, is invoked by the callback as a helper, but still within the same thread that originated the call to the callback function in the first place.

Sorry for the discontinuity in the thread in the mailing list.  I wasn't signed up the for mailing list before sending the first message, and I can't figure out how to reply to an archived message.  Doing my best with copy and paste.

First - thanks, Lorenzo.  Your message caused me to re-affirm that I was doing the right thing in the code and that I must have made a mistake somewhere else.

For any interested - As it turns out the problem was simple testing/operator error.  I was testing with Firefox and trying to go to the same URL from 2 tabs at the same time.  I wasn't seeing the request getting processed in the server because -Firefox- was serializing them (that is, starting the second request only after the first request returned).  I assume it was just trying to be helpful since the URLs were the same, expecting a cache hit for the second request or something.  I just wasn't expecting that behavior and after numerous attempts, assumed the problem was in my webserver code.  I'm guessing other browsers would behave the same way.  I feel a little foolish for not figuring this out earlier, but that's the way it goes.

In any case, like Lorenzo, I can now confirm that microhttpd will work quite well with long-polling if you want to roll your own solution.  If you do some stuff to keep track of sessions (via cookies), you can also detect multiple 'comet' requests from a single client and respond accordingly (moving to fast-polling to prevent locking up browsers that only allow a couple connections to a single server).  You have to handle all this yourself, of course, but it can be done without too much trouble with some smart locking/waiting/timeout code and a reasonable protocol back up to the browser.

For any finding this from a search, you could also consider using the Bayeux protocol (from CometD).  I don't need that generic of a solution so I don't want to mess with the complexity, but I see no reason why you couldn't make that work if you were so inclined.  Understanding the ins-and-outs of comet prior to rolling my own solution has been helpful for me.  Also - for those thinking about CometD - while I miss the feature-richness you get from pre-made Java-based webserver solutions, I have really enjoyed the speed and control microhttpd provides, and I do not regret the choice to use it at all - especially on an embedded system.


reply via email to

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