è possibile creare un thread in background dallo script WSGI prima volta che viene importato.
import threading
import time
def do_stuff():
time.sleep(60)
... do periodic job
_thread = threading.Thread(target=do_stuff)
_thread.setDaemon(True)
_thread.start()
Per far funzionare tutto questo anche se si dovrebbe essere utilizzando un solo processo demone altrimenti ogni processo avrebbe fatto la stessa cosa che probabilmente non si vuole.
Se si utilizza più processi in un gruppo di processi daemon, un'alternativa è creare un gruppo di processi daemon speciale il cui unico scopo è eseguire questo thread in background. In altre parole, il processo non riceve alcuna richiesta.
È possibile farlo avendo:
WSGIDaemonProcess django-jobs processes=1 threads=1
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
process-group=django-jobs application-group=%{GLOBAL}
La direttiva WSGIImportScript dice di caricare lo script ed eseguirlo all'avvio nel contesto del gruppo processo 'django-posti di lavoro'.
Per evitare di dover più script, ho sottolineato che a quello che sarebbe stato il file originale di script WSGI utilizzato per WSGIScriptAlias. Noi non vogliamo che venga eseguito quando viene caricato da tale direttiva, però, così facciamo:
import mod_wsgi
if mod_wsgi.process_group == 'django-jobs':
_thread = threading.Thread(target=do_stuff)
_thread.setDaemon(True)
_thread.start()
Qui si esamina il nome del gruppo di processo demone e solo quando viene eseguito avviato nell'ambito del processo demone speciale gruppo istituito con processo unico solo per questo.
Nel complesso si sta semplicemente utilizzando Apache come un gestore di processo glorioso grande, anche se uno che è già noto per essere robusto. È un po 'eccessivo dato che questo processo consumerà memoria aggiuntiva oltre a quelle che accettano e gestiscono le richieste, ma a seconda della complessità di ciò che stai facendo può comunque essere utile.
Un aspetto carino di questo è che poiché è ancora un'applicazione Django completa, è possibile mappare URL specifici solo per questo processo e quindi fornire un'API remota per gestire o monitorare l'attività in background e cosa sta facendo .
WSGIDaemonProcess django-jobs processes=1 threads=1
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
process-group=django-jobs application-group=%{GLOBAL}
WSGIDaemonProcess django-site processes=4 threads=5
WSGIScriptAlias//usr/local/django/mysite/apache/django.wsgi
WSGIProcessGroup django-site
WSGIApplicationGroup %{GLOBAL}
<Location /admin>
WSGIProcessGroup django-jobs
</Location>
Qui, tutti gli URL tranne per le cose di sotto run/admin in 'django-site', con/admin nel 'django-posti di lavoro'.
In ogni caso, che affronta la questione specifica di farlo all'interno del Apache mod_wsgi processo demone come richiesto.
Come indicato, l'alternativa è quella di avere uno script da riga di comando che imposta e carica Django e fa il lavoro ed esegue quello da un cron job.Uno script da riga di comando indica l'utilizzo occasionale di memoria temporanea, ma il costo di avvio per il lavoro è più elevato in quanto è necessario caricare ogni volta ogni cosa.
Sono andato con Celery. Ha funzionato come un fascino. –
un'attività cron non viene eseguita continuamente in background, ma inizia in un dato momento e termina quando è pronta. Dato che i comandi di django richiedono un tempo di avvio di 1.5 secondi (a partire dalla complessità dei modelli), questo non è solitamente il modo di farlo quando sono necessarie prestazioni elevate. – FeedTheWeb
È ancora valido? Se sì, quale sarebbe un buon modo di demonizzare l'attività di Celery che farebbe la mia lunga elaborazione? –