2010-06-29 1 views
5

Mi sono guardato un po 'in giro ma non riesco a risolvere questo problema. Mi piacerebbe eseguire uno script python in una vista della mia app django. Ho inserito il codice che vorrei eseguire all'interno di un comando di gestione di django in modo che sia accessibile tramite la riga di comando python manage.py command-name. Ho quindi provato a eseguire questo comando utilizzando subprocess.Popen("python manage.py command-name",shell=True).Esecuzione di uno script python utilizzando subprocess.Popen() in una vista django

Tuttavia, questo comando potrebbe richiedere del tempo per l'esecuzione, quindi mi piacerebbe che la vista continuasse e consentisse l'esecuzione dello script in background. Utilizzando subprocess.Popen solo sembra causare la visualizzazione di appendere fino a quando lo script ha finito, così ho provato con un filo (segue another SA domanda):

class SubprocessThread(threading.Thread): 
def __init__(self, c): 
    self.command = c 
    self.stdout = None 
    self.stderr = None 
    threading.Thread.__init__(self) 

def run(self): 
    p = subprocess.Popen(self.command, 
         shell=True, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 

    self.stdout, self.stderr = p.communicate() 

e poi eseguirla:

t = SubprocessThread("python manage.py command-name") 
t.setDaemon(True) 
t.start() 
t.join() 

Tuttavia, la vista si blocca ancora: il cursore ha un simbolo occupato e l'AJAX nella pagina non viene caricato. In caso contrario, l'html della pagina sembra caricare bene e i comandi nella vista dopo che la chiamata al thread sembra terminare normalmente (prima che lo script finisca). Qualcuno può aiutarmi? Mi piacerebbe che lo script eseguisse e facesse le sue cose senza ostacolare la vista o le chiamate AJAX sulla pagina.

+0

Io uso regolarmente un modello simile (con un 'subprocess', perché un' thread' viene ucciso quando la funzione termina vista), e ho regolarmente dimentica di restituire qualcosa in visualizza la funzione, bloccando il browser. Quindi, do la colpa ai sub-dipendenti, mentre mi sono appena dimenticato di restituire un 'HttpResponse'. Controllalo! – Dunatotatos

risposta

3

Forse si dovrebbe usare celery

Il sedano è una coda di coda compito/lavoro basato su messaggio distribuito passaggio. Si focalizzata sul funzionamento in tempo reale

1

Ho sprecato un sacco di tempo cercando di implementare qualcosa di simile, ma ho avuto gli stessi problemi di te. Alla fine, ho rinunciato e ho implementato una coda di beanstalk per gestire il lavoro.

http://kr.github.com/beanstalkd/

ho messo un id sulla coda nella vista Django, e poi hanno un comando di gestione per eseguire il consumatore (guardato da supervisord).

L'uso di una coda significa che è possibile espandere a più utenti e consente di gestire meglio il carico (sospendendo il consumatore se necessario senza perdere il lavoro richiesto).