SOcket Activator/Deactivator: like inetd but not really and for 2017
C Ruby
Latest commit 5cbae25 Jan 23, 2017 @myfreeweb bundle exec doc
Permalink
Failed to load latest commit information.
.gitignore initial commit Jan 2, 2017
CODE_OF_CONDUCT.md initial commit Jan 2, 2017
README.md bundle exec doc Jan 22, 2017
UNLICENSE initial commit Jan 2, 2017
config.ru initial commit Jan 2, 2017
soad.c add custom signal support Jan 20, 2017
test_server.rb initial commit Jan 2, 2017

README.md

soad: SOcket Activator/Deactivator unlicense

A simple modern tool for running web applications on demand and stopping them after a period of inactivity.

Back in the day, web apps used something like CGI or inetd, where one request got one UNIX process that would, well, process it — and quit. This meant that your whole app would be loaded and unloaded once per request, which is especially slow when you use big frameworks written in scripting languages. But it also meant that when no requests were being processed, no resources (such as RAM) were held. Of course, these days no one cares about not holding resources and this approach is completely dead OH WAIT NO IT'S THE COOL NEW THING.

But what I want to do is to run many rarely used services on a VPS with low RAM. Modern web app servers are designed to run on a socket until you stop them. So what if I want to stop inactive services?

Installation

Should work on any modern UNIX-like system.

$ cc -lpthread -o soad soad.c

And put soad where you keep your binaries.

Usage

First, your web server needs to support socket activation. Either by explicitly specifying a file descriptor via something like an fd://3 argument, or by using the tiny metadata protocol from systemd — the LISTEN_PID, LISTEN_FDS and LISTEN_FDNAMES environment variables.

It also needs to shut down gracefully on a signal (SIGTERM is sent by default, customize by passing the signal number as -S/--shutdown-signal).

Some libraries and apps for that:

(You can implement your own in 5 minutes, all you need to do is create a socket object from a file descriptor. See test_server.rb for a tiny example.)

Now, to run your app on a UNIX domain socket, something like this:

$ soad -s /var/run/myapp.sock -t 240 -- bundle exec --keep-file-descriptors puma -b unix:/var/run/myapp.sock
$ soad -s /var/run/myapp.sock -t 240 -- gunicorn app:app
$ soad -s /var/run/pyapp.sock -t 240 -- uwsgi --master --hook-master-start "unix_signal:15 gracefully_kill_them_all" --wsgi-file app.py --callable app --lazy-apps

The -t/--time-until-stop argument is the number of seconds the app will be allowed to run without any activity. (Activity is determined by incoming socket connections, so basically the number of seconds since the last incoming request.)

Point your reverse proxy to that socket and enjoy.

Contributing

Please feel free to submit pull requests!

By participating in this project you agree to follow the Contributor Code of Conduct.

License

This is free and unencumbered software released into the public domain.
For more information, please refer to the UNLICENSE file or unlicense.org.