Wishlist for a service framework and/or manager
I maintain code for a few daemons/services written in Perl (most of them serve requests by forking/preforking). Reading post on Ubic, I started to feel that I am reinventing a lot of wheels. Currently I am doing these by writing my own code, as much as which I hope can be offloaded to CPAN in the future:
- Autorestart when process size is becoming too big. We need to do this gracefully, meaning wait until there is no more clients being serviced, unless process size really gets too big in which case we need to restart immediately. Checking period can be configured.
- Autorestart if script or modules change on disk. Also needs to be done gracefully. This is usually being recommended to be used only on development environment, but I use this too in production, for ease of deployment. But we need to check first (e.g. via "perl -c" or "eval + require" whether the new code from disk is okay.
- Avoid duplicate instance (currently always using Proc::PID::File, but I'm open to better mechanism).
- Limit clients concurrency. Sometimes this is simple (a single limit for all clients) and sometimes not so much (different limits for different IP/IP blocks/authenticated users/groups/etc).
- Reap dead child processes and maintain a count of child processes.
- Handle timed out clients. This is rather cumbersome with blocking I/O.
- Write init script. This is the part I dislike the most, since there are tons of different OS flavors out there, and with more recent efforts like upstart, launchd, systemd, sooner or later I will certainly have to write different init scripts. I wish there is something equivalent to PSGI/Plack for general services, which can plug my code to whatever service manager might be out there.
Hi!
First three features can be done in Ubic already:
- process size check can be done via custom status checks
- autorestart can be done via custom status checks too
- duplicate instance is in-built already if you are using Ubic::Daemon (or you can use any other daemonizing module from CPAN as well)
Client concurrency control and handling timeouts is not service manager's tasks IMO.
Init scripts are *trivial* in ubic, actually, it's one line:
$ cat /etc/init.d/any-ubic-service
use Ubic::Run;
Ubic::Run checks $0, so you don't have to pass service name to it.
About graceful restarts - i believe the proper way to do them would be to use Server-Starter.
Combination of start_server, ubic's SimpleDaemon and custom reload implementation which sends SIGHUP to process should work, although i never tried Server::Starter myself (and there is no API in Ubic yet to get pid of service's process... but this can be fixed).
> I wish there is something equivalent to PSGI/Plack for general services
I think making *all* service managers pluggable is neither possible nor necessary. upstart, systemd, launchd, classic /sbin/init are all too low-level.
It is completely normal to run your own service manager which don't try to be pid 1 in user space.
Thinking about it, Ubic services are similar to PSGI :)
@Vyacheslav: Thanks for the comments. I'll be checking Server::Starter (glancing the docs, it's not clear whether the superdaemon will wait for the current connecting clients to finish, assuming it will). Also, will definitely try out Ubic!