2009-10-29 12 views
6

Ho un normale sito Django in esecuzione. Inoltre, c'è un altro processo contorto, che ascolta le notifiche di presenza di Jabber e aggiorna il Django DB usando l'ORM di Django.Come rinviare un'operazione di Django DB da Twisted?

Finora funziona come chiamo i corrispondenti modelli Django (dopo aver configurato correttamente l'ambiente delle impostazioni). Questo, tuttavia, blocca l'app Twisted, che non è quello che voglio.

Dato che sono nuovo di Twisted non so, quale sarebbe il modo migliore per accedere al Django DB (tramite il suo ORM) in modo non bloccante utilizzando i differiti.

  1. deferredGenerator?
  2. twisted.enterprise.adbapi? (aggirare l'ORM?)
  3. ???

Se il messaggio di presenza viene analizzato voglio salvare in Django DB che l'utente con jid_str è online/offline (utilizzando il modello di Django UserProfile). Lo faccio con quella funzione:

def django_useravailable(jid_str, user_available): 
    try: 
     userhost = jid.JID(jid_str).userhost() 
     user = UserProfile.objects.get(im_jabber_name=userhost) 
     user.im_jabber_online = user_available 
     user.save() 
     return jid_str, user_available 
    except Exception, e: 
     print e 
    raise jid_str, user_available,e 

Attualmente, invoco con: "Ho un normale sito Django esecuzione"

d = threads.deferToThread(django_useravailable, from_attr, user_available) 
d.addCallback(self.success) 
d.addErrback(self.failure) 
+1

Inserisci il codice, in particolare la parte che "blocca" la tua app. – ohnoes

risposta

1

Presumibilmente in Apache utilizzando mod_wsgi o simile.

Se si utilizza mod_wsgi incorporato in Apache, si noti che Apache è multi-thread e i thread Python sono schiacciati nel threading di Apache. L'analisi di ciò che sta bloccando potrebbe diventare icky.

Se stai utilizzando mod_wsgi in modalità daemon (che dovresti essere), il tuo Django è un processo separato.

Perché non continuare questo schema di progettazione e rendere il tuo "jabber listener" un processo separato.

Se si desidera che questo processo venga eseguito su qualsiasi numero di server, farlo avviare da init.rc o cron.

Poiché è un processo separato, non sarà in competizione per l'attenzione. Il tuo processo Django viene eseguito rapidamente e il tuo ascoltatore Jabber funziona in modo indipendente.

+0

Mi piacerebbe avere l'opportunità di migrare il gestore notificaiton di presenza su un altro server quando necessario. Con la soluzione di processo che non è facilmente possibile. Inoltre, mi piace l'appraoch asincrona distorta, che ritengo possa gestire enormi quantità di modifiche alle notifiche. Suppongo che ci saranno molte più notificazioni di quelle dei siti web. –

1

Ho avuto successo utilizzando il metodo che hai descritto come metodo attuale. Scoprirai leggendo i documenti che la DB api intrecciata usa i thread sotto il cofano perché la maggior parte delle librerie SQL ha un'API di blocco.

Ho un server contorto che salva i dati dai monitor di alimentazione nel campo, e lo fa avviando un sottoprogramma ogni tanto e chiamando il mio codice di salvataggio Django. Puoi leggere di più su my live data collection pipeline (che è un link al blog).

Stai dicendo che stai avviando una sottotrama e che è ancora blocco?

+0

Ma la ragione per usare twisted è che non vogliamo usare thread. Se devo attenermi all'attuale versione con thread, non ho benefici nell'uso di twisted. Potrei quindi utilizzare direttamente i thread del processo Django. –

+0

Sì, lo odio anche per quella stessa ragione. Almeno è possibile garantire l'avvio di un numero limitato di thread di database (ad esempio, gestisco 1000 connessioni client e raggruppa abilmente i loro accessi e thread di database). L'utilizzo del database è solo una piccola parte delle mie connessioni a lungo termine gestite da twisted, quindi è giusto girare un thread su richiesta per me. –

0

Ho un'applicazione Twisted in esecuzione in cui utilizzo Django ORM. Non lo sto rimandando. So che è sbagliato, ma non ho ancora avuto problemi.

+0

Un po 'irrilevante, non è vero? –