This week a lot of hours has been spent working with the http
refactoring, finishing location plugin chains and implementing some
general improvements.
A large emphasis has been put on making the http implementation support
both current and new plugins.
But while the new plugin api is protocol agnostic, the current plugins
can not work with SPDY or HTTP/2.0.

# HTTP refactoring

The result of the http work is a separation of the code into three parts,
one part generic, one part to support the old plugin system and another
to integrate with the new plugin api.
Due to how current plugins work, they are not completely isolated as
stages need to be called during different stages of processing, but it
is close enough.

>From a high level view the http module processes request in four stages,
parsing requests, check request data, process request data and finally
produce a response.
This view is valid both the current http code and the new, but it is
more cleanly separated now.
Previously, members of `struct session_request` required by plugins were
set during all stages of processing, but now these are all setup during
the processing stage.
This will make it very simple to disable the old plugin api,
the only thing required is the removal of 4-5 function calls.
Until then, monkey will be able to use both old and new plugins
seamlessly.

## Static plugin

The static file plugin now supports http ranges, does proper path
resolution, directory redirect and supports both chunked and fixed size
responses.
All file handling is done by this plugin, reducing the complexity of the
http code.

[Code](https://github.com/ksonny/monkey/tree/plugin_next)

# Location plugin chains

This change adds a new type of section in the vhost, 'Locations'.
In these sections you can have two entries, 'Path' and 'Plugins'.
Any request where the 'Path' data matches uri path will only be handled
by the plugins listed in 'Plugins'.
Plugins are matched against their shortname, with 'none' being a special
keyword.

The plugins listed will be asked to handle the request in the order they
are stated, allowing changing plugin priority by configuration.

For current monkey master, static files will always be processed for all
locations whether there are any plugins registered for that location or
not, but with the new plugin api and the addition of the `static`
plugin, it is possible to choose if locations should serve
static file or not.

        [Location]
                Path /
                Plugins static

        [Location]
                Path /protected/
                Plugins auth static

        [Location]
                Path /disabled/
                plugins none

The location with the longest matching path prefix will be used, and
Plugins are not inherited.

[Code](https://github.com/ksonny/monkey/tree/chain_plugin)

# Queued file entry with destructor

The new plugin api uses a queue with supports for static and heap
allocated buffers as well as files.

This week I've added support for customizing the file descriptor close
functions, allowing it to be excluded or replaced.
It allow for the same file descriptors to be used for multiple requests,
effectively caching file descriptors.
This may not seem like such a great thing, but open() and stat() can be
very expensive on some systems.

Support is not yet added to the plugin api, but the changes in mk_queue
is already in place.

[Code](https://github.com/ksonny/monkey/tree/plugin_next)

# Plugin event handling

Five new functions has been added to the new plugin api for tracking
backend file descriptor events.

        struct sched_connection *
        mk_event_add(const struct mk_plugin *handler,
                int fd,
                int events,
                void *data);

        int
        mk_event_del(struct sched_connection *connection);

        int
        mk_event_change(struct sched_conneciton *connection, int events);

        void *
        mk_event_data(struct sched_connection *connection);

        int
        mk_event_socket(struct sched_connection *connection);

Their name and arguments may change but this is their current
prototypes.
The data argument in `mk_event_add()` can be retrieved using
`mk_event_data()`.

[Code](https://github.com/ksonny/monkey/tree/plugin_next)

# Event sleep/wakeup handling

On top of previous week connection hook changes I've implemented an
optimization that reduces the complexity of sleep/wakeup of epoll events
by reusing the sched_connection structure.
The optimization removes one red-black tree lookup by merging it's
functionality into a structure tracked by another red-black tree.

Currently, a thread local red-black tree keeps mk_epoll_state entries
for every connection registered with the worker epoll instance.
There also exists another red-black tree with sched_connection entries
containing connection hooks, initalization time and some state for all
connections registered with the local scheduler.
These two trees both uses the socket file descriptor for lookup.

This change merges the functionality of mk_epoll_state into a single
32bit field that already exists in sched_connection.
While the O complexity of two red-black tree operations is the
same as one, it is still an improvement.

[Code](https://github.com/ksonny/monkey/tree/event_sleep)

[Github](https://github.com/ksonny/)
[Blog](https://lotrax.org/gsoc/gsoc-2013-status-future-protocols-week-5.html)

-- 
Sonny Karlsson
_______________________________________________
Monkey mailing list
[email protected]
http://lists.monkey-project.com/listinfo/monkey

Reply via email to