DGoiko
DGoiko

Reputation: 378

Python process as proper daemon (and optionally Windows Service)

I'm implementing a program that runs 24/7. It is continuously performing tasks every 15 seconds or so, however, some tasks may take arbitrary time to run (more than 15 secs), and it is not recommended to perform other operations on the same worker while it's running the task (some tasks involve the deployment and elimination of virtual machine instances). Doing this with an stateless cronjob would require a complex locks logic which will be hardly scalable, so it is not an option.

The program has a complex and heavy state, is basically the core or a big cluster that handles job scheduling, checking status, restarting dead jobs and updating the final results, so de idea is to have it always running as the core of the system.

Right now the complete software is implemented as a subclass of threading.Thread with all the concurrency considerations already solved.

The endpoint of the system is a VERY SIMPLE script which reads configs from arguments and files and initialices the threaded class with'em. After that, it runs the start() method and waits forever, relaunching the main class if it crashes somehow.

What I want to do is to implement this simple class as a well-behaved daemon process (right now I'm using nohup and & to get things done) with start/stop AND a simple status method which prints info about running jobs, size of current cluster, etc, all simple text. Right now I've a signal listener which emulates stop() and status() by gracefully stopping the threads (if needed) and printing output to a file.

The remote cluster and it's communication/schedule logic is a custom implementation using Pyro4, so one option would be to register the main process itself in the Pyro Daemon, so one alternative would be to register the daemonizable class itself and use some custom python code to connect to it and get the status, however, I think this is overkill and relies on pyro daemon, which adds innecesary failure points to the system.

I came across several libraries that claim to make proper daemons:

Those classes look robust and simple enough to fit my current needs (I haven't found out how to make the status() part yet, however, it must be easy). Is there any other library that does it in a more robust way? right now I've no time to spend performing stability checks on the daemon library, so even if it may be a bit opinion-based I'd like to know your thoughts and practical experience on this.

All this is about linux daemons, however, is there any SIMPLE class that handles windows services as well as linux daemons? My current program is linux-only due to other external limitations but in the future it would be nice to avoid programming two different branches.

For my current project I don't need anything more than the exposed above, however, thinking about the future I'd like to be able to SEND some information FROM terminal TO the daemons. Nothing really complex, just commands with simple string / numeric payload as arguments.

For example, it would be nice to have a "reload_config" function which allows me to pass a new configuration file location from console. Right now, to reload config I modify the CURRENT config file and tell the process to read it again using a signal. This reduces the feasible functions that can be implemented using this (you can use a temporal file in a known location to store the command and make the client read it, but it is not a clean solution either)

As far as I know, the only proper ways to achieve this (besides using a communication file) are:

**NOTE: Currently I'm using logging.Logger to log to a file directly, could this be a problem? As far as I know (and guess) it isn't, but you never know...

Also, according to this post's first answer, "systemd makes many daemons obsolete", I'm not very used to systemd (have been reluctant to upgrade to modern OS's until I've not been able to delay it any longer), however, which this method I can just do what I'm doing now: catching and properly handling close signals and autostart/kill the script from systemd, which seems not to be enough.

Although, it seems that unless I implement more complex client/servers I won't be able to send commands with arguments to my services, am I wrong? The ideal situation would be to be able to launch commands like this:

systemctl custom_command python_service custom_argument

although, I dont think systemd supports anything like this, am I wrong?

Anyway, for the purpose of the main questions, those capabilities would suffice:

systemctl start python_service 
systemctl stop python_service 
systemctl restart python_service 
systemctl reload python_service 
systemctl status python_service 

Upvotes: 1

Views: 641

Answers (1)

bignose
bignose

Reputation: 32347

I think you are primarily asking:

is there any SIMPLE class that handles windows services as well as linux daemons?

Because those two are very different, I think the answer must be: no.

Any class which handled both of those would be quite complex, by definition.

Upvotes: 2

Related Questions