Hi.
Its time to add asynchronous extensions to the WSGI module.
I’m developing a WSGI application where I need to talk with a web
service on the Internet, so it is very important to use an
asynchronous HTTP client.
I have choose libcurl, since it is well designed and there is a wrapper
for Python.
Here is what I’m thinking to do:
-
when libcurl creates a socket, I create an associated nginx
connection, by calling the ngx_get_connection function
-
when I need a read notifycation, I call ngx_handle_read_event
-
when I need a read notifycation, I call ngx_handle_write_event
-
when I’m done with libcurl, I call ngx_close_connection
Of course I have to setup the timeouts, but is this all I need to do?
The event structure has a lot of members, and I’m not sure to understand
all of them.
Also, there is a problem with ngx_close_connetion: it will close the
socket, but the socket is owned by libcurl, so I will need to patch it.
Thanks Manlio P.
Manlio P. ha scritto:
Hi.
Its time to add asynchronous extensions to the WSGI module.
I’m developing a WSGI application where I need to talk with a web
service on the Internet, so it is very important to use an
asynchronous HTTP client.
[…]
Some more detailed questions:
-
Can I use NGX_READ_EVENT and NGX_WRITE_EVENT as bit masks?
As an example:
flags = NGX_READ_EVENT | NGX_WRITE_EVENT
if (flags & NGX_READ_EVENT) {…}
-
What’s the meaning of active, disabled, ready and oneshot attributes
in the event structure?
And what about the write attribute?
-
Should I set event->ready = 0 after I have handled an event?
Are there other things that I need to do in the event handler?
Note that I do not need to write or read from the socket.
-
The handle_write_event function remove the event when
wev->active && wev->ready.
What’s the rationale?
-
It seems that the event module does not allow me to register an
event for both read and write notifications.
This can be a problem for me, since I have to manage two
callbacks…
I have to check.
Moreover there is a difference in how events are handled in the
select and poll module, as an example.
For the select module it is the passed in event object that is
posted, and I have no way to know if the socket is ready for reading
or writing.
With the poll module it is the event->data->read and/or
event->data->write that is posted.
What’s the rationale?
I’m not an expert, but why the select module does not do the same as
the poll module?
-
The event module assumes that the event data is the connection
structure.
What should I do if I need to keep more data?
As an example, in my case I need to store the peer connection but
also the http request.
Thanks Manlio P.
Manlio P. ha scritto:
select and poll module, as an example.
the poll module?
Ok, forget this ;-).
For adding both read and write events I have only to call add_event two
times, or just use the handle_read_event and handle_write_event
functions.
There is still the problem of having to handle read and write events
separately:
curl_multi_socket_action
(curl_multi_socket)
can handle both read and write event in one call.
Thanks Manlio P.
Igor S. ha scritto:
[…]
[…]
Next answers later.
Igor, thanks for the documentation!
I have solved most of the problems, and I have a working draft.
However I have found a problem, and unfortunately I’m not expert of
epoll internals.
As I have written, I’m using libcurl as the HTTP client.
Here is the operations I do:
-
libcurl tells me that it is waiting for the socket to be writeable,
and I call handle_write_event(self->c->write, 0)
Since this is the first time that I see the socket I call
ngx_get_connection and after this I call ngx_add_conn (if defined)
-
libcurl tells me to deregister the socket, and I call
ngx_del_event(self->c->write, NGX_WRITE_EVENT, 0)
-
libcurl tells me that it is waiting for the socket to be readable,
and I call ngx_handle_read_event(self->c->read, 0),
but I get an error:
epoll_ctl(EPOLL_CTL_ADD, 8) failed (17: File exists)
What I’m doing wrong?
Thanks Manlio P.
On Tue, Mar 04, 2008 at 01:30:07PM +0100, Manlio P. wrote:
Some more detailed questions:
- Can I use NGX_READ_EVENT and NGX_WRITE_EVENT as bit masks?
As an example:
flags = NGX_READ_EVENT | NGX_WRITE_EVENT
if (flags & NGX_READ_EVENT) {…}
No, they can not ORed at least in kqueue method.
-
What’s the meaning of active, disabled, ready and oneshot attributes
in the event structure?
And what about the write attribute?
/*
* the event was passed or would be passed to a kernel;
* in aio mode - operation was posted.
*/
unsigned active:1;
/* the ready event; in aio mode 0 means that no operation can be
posted */
unsigned ready:1;
disabled: event filter has been allocated in kernel, but disabled
now.
The optimization that allows to avoid lock aquiring in
kernel
allocation.
oneshot: event filter is oneshot, Solaris event port, kqueue's
EV_ONESHOT,
epoll’s EPOLLONESHOT.
write: write event filter (NGX_WRITE_EVENT).
Next answers later.