[Libwebsockets] lwsws SIGHUP / configuration reload support in master

Andy Green andy at warmcat.com
Tue Dec 6 05:10:26 CET 2016


Hi -

Due to overwhelming popular demand ^^ I have implemented support for
configuration reload in lwsws.  I have a use for it even if nobody else
presently does.

https://github.com/warmcat/libwebsockets/commit/d8ab5631644cbf3ea5a91a1
055fd56c0b9e5ddf5

The link might move around, it's a patch called "context deprecation".

```
This lets you send lwsws a SIGHUP and have it reload the configuration.

It does this without affecting existing connections, which continue to
run under the old configuration until no more old connections are left.

New connections are made to the new context using the new
configuration.

Notes:

1) Only lwsws has the code to handle the signal, you can cut and paste
it
into your own server if needed

2) lws_context_destroy() has been split into two pieces... the reason
for
the split is the first part closes the per-vhost protocols, but since
they may have created libuv objects in the per-vhost protocol storage,
these cannot be freed until after the loop has been run.

That's the purpose of the second part of the context destruction,
lws_context_destroy2().

For compatibility, if you are not using libuv, the first part calls the
second part.  However if you are using libuv, you must now call the
second part from your own main.c after the first part.

3) There are also significant updates to the system-status plugin, so
you
can clearly see what is going on with the deprecated contexts.
```

The docs in lwsws are here

https://libwebsockets.org/lws-api-doc-master/html/md_README_8lwsws.html

```
Lwsws Configuration Reload

You may send lwsws a HUP signal, by, eg
$ sudo killall -HUP lwsws

This causes lwsws to reload and apply the current configuration,
without dropping any existing connections or terminating the lwsws
process.

It does this by "deprecating" the existing context, and removing and
closing its listen sockets, but otherwise allowing it to continue to
run, until all of its open connections close.

At the same time a new context is created, using the new configuration,
and it creates new listen sockets according to the new configuration,
so any new incoming connections are accepted by the new context.

When a deprecated context has no open connections left, it is destroyed
automatically.

It's okay to reload the configuration multiple times without taking
care about any deprecated contexts still existing; lws manages them
with a linked-list.

The new configuration may differ from the original one in arbitrary
ways, the new context is created from scratch each time without
reference to the original one.

Notes

1) Currently protocol plugins are not reloaded.

2) Your protocol must take care about per-vhost storage to work with
this, and not just store things in global variables. This is because
the original protocol instance will be logically destroyed when the
original context is destroyed; if variables are stored globally then
they will reflect the destruction flow even for the new replacement
context.

Your protocol should use a per_vhost_data struct like the
dumb_increment and mirror protocol plugins do. This will be created and
destroyed per-vhost, and the vhosts are specific to each protocol.

The provided example plugins already use per-vhost protocol storage and
can be used as a template for how to do it correctly.

3) Protocols that provide a "shared world" like mirror will have as
many "worlds" as there are contexts still active. People connected to a
deprecated context remain connected to the existing peers. But any new
connections will apply to the new context, which does not share per-
vhost "shared world" data with the deprecated context. That means no
new connections on the deprecated context, ie a "shrinking world" for
those guys, and a "growing world" for people who connect after the
SIGHUP.

The advantage of this is the two contexts may be configured arbitrarily
differently, and although it is not supported yet, it is possible for
the two contexts to be running two completely different protocol
plugins, with different internal struct sizes, etc.
```

This is an very special case for having multiple contexts indeed.  For
everything else, you should just use one context.

You can test it easily enough...

 - run lwsws with the test server or something else that holds open a
connection

 - open a browser on it

 - change the config to have the vhost listen to a different port, or
change / add / delete something else noticeable

 - killall -HUP lwsws

 - open a browser on it

Both browser sessions work OK, reflecting the original and the new
config.

If you set up your lwsws vhost to use the lws-server-status plugin
protocol

       "lws-server-status": {
         "status": "ok",
         "update-ms": "5000"
       }

you can watch the situation inside lwsws in terms of how many active
contexts left alive, see them close when they lose their last
connection etc.

Bug reports or patches welcome.

-Andy





More information about the Libwebsockets mailing list