|
From: | Kenneth Mastro |
Subject: | Re: [libmicrohttpd] Complete request on fd becoming ready |
Date: | Mon, 27 Mar 2017 09:41:52 -0400 |
Hi!
Thank you for your reply, I think my original question wasn't very well
posed. Let me try to rephrase it.
In the epoll + threadpool configuration of MHD, MHD itself uses an
epoll() type loop to service fds that are ready to send or receive
traffic from clients. I/O is non-blocking and when MHD is waiting on
the kernel to finish sending traffic back to the client, or waiting on
traffic from the client, the fd goes back into the wait list of epoll.
What I'm hoping to achieve is to receive traffic from my backend in a
similar manner. So I'm hoping for something like this:
* MHD mainloop accept()'s a new connection
* MHD pushes this new connection to a thread on its threadpool
* MHD runs the request handler for the connection
* Request handler parses the HTTP request and constructs a request in
the binary protocol.
* Request handler opens a non-blocking connection to the backend
server.
< .. magic .. >
* The request gets sent to the backend server once the connection to
the backend becomes ready for writing.
< .. more magic .. >
* Once the listening FD for the backend connection becomes ready,
create a response object and send it to the client to have MHD then use
its normal async loop to service the client.
What I'm thinking of doing now is to do something like this in the
request handler:
* Send the parsed request to a separate thread that has its own epoll()
loop, along with struct MHD_Connection *connection.
* Return MHD_OK
* In the separate thread, deal with the request like normal, when the
backend socket becomes ready for reading construct the MHD_Response and
call MHD_queue_response (connection, MHD_HTTP_OK, response);
* Destroy the response object
Now, I'm not entirely sure if this will work for a variety of reasons.
I don't know if it's safe toe call MHD_queue_response() in this manner
for instance.
I was also wondering if there was a way of combining these loops so I
don't have to do it this way. Maybe if external select does what I
think it does I could use that as my programs' main loop instead of
MHD's, but I don't know if that will actually be any better.
On Mon, 2017-03-27 at 08:33 -0400, Kenneth Mastro wrote:
>
> If traffic/request volume is sufficiently low, the simplest thing to
> do is use MHD's 'thread per connection' mode and just do the back-end
> I/O in that thread. Send the request, wait for the response, and
> send the result back out MHD to the caller. Just make sure the back-
> end is thread-safe and/or the MHD side waits for a request to finish
> before sending another (even if it's simply by using a mutex). It's
> hard to know what to suggest without a lot more info.
This is more or less what I'm doing now. Doing blocking I/O to the
backend service in a thread per connection.
> In short - this sounds a lot more like a threading problem than any
> problem you might have with MHD.
It's not so much a 'problem' as that I'm trying to figure out how to
optimize my program so it can be fully asynchronous.
>
>
> On Sun, Mar 26, 2017 at 8:44 PM, Hein-Pieter van Braam <address@hidden>
> wrote:
> > Hello all,
> >
> > I am writing an MHD application where the MHD HTTP server acts as a
> > proxy between a HTTP REST API and a different binary protocol on
> > the
> > backend. My MHD application opens a new TCP connection to the
> > backend,
> > translates the request, and waits for an answer.
> >
> > The waiting on an answer part would normally be blocking, and
> > reading
> > the MHD manual I can't come up with a way of using async io here.
> > What
> > would an MHD application look like that creates response objects
> > from
> > (another) polling loop, and where do I even place this loop?
> >
> > I have been thinking of a variety of convoluted things with
> > threads,
> > then I figured it'd probably be better to ask the experts :)
> >
> > Thanks!
> >
> > - HP
> >
> >
>
>
[Prev in Thread] | Current Thread | [Next in Thread] |