>
> Date: Wed, 07 May 2014 14:24:40 +0200
> From: Christian Grothoff <[email protected]>
> To: [email protected]
> Subject: Re: [libmicrohttpd] Stuck Single Threaded
> Message-ID: <[email protected]>
> 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