Question

I am trying to have a cron like process that gets run every 60 seconds. I do not want it to be executed by every thread. Is there a way to specify which uwsgi worker will respond to a signal?

I currently have uwsgi configured to have a master process, lazy mode, and 2 workers with 2 threads.

I have the following code directly in my wsgi file.

def sig_test(signum):
    print "do this thing" + signum

uwsgi.register_signal(99, "", sig_test)
uwsgi.add_timer(99, 60)

The signal registration segment gets run in both threads, and leads to the following error:

Traceback (most recent call last):
File "/var/local/wsgi.wsgi", line 153, in <module>
uwsgi.register_signal(99, "worker 1", sig_test)
ValueError: unable to register signal
Wed Jan 15 16:01:57 2014 - unable to load app 0 (mountpoint='') (callable not found or import error)
Wed Jan 15 16:01:57 2014 - *** no app loaded. going in full dynamic mode ***
Wed Jan 15 16:02:08 2014 - [uwsgi-signal] you have registered this signal in worker 2 memory area, only that process will be able to run it
Wed Jan 15 16:02:08 2014 - error managing signal 99 on worker 1
Was it helpful?

Solution

Use Python decorators: timer and possibly spool. Per the docs, Signal-based decorators execute the signal handler in the first available worker. However, in lazy mode the app is loaded and executed in each worker separately, and uWSGI is not smart enough to create the timer only once. The simplest fix would be using shared-import config option and init the timer there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top