2012-10-22 10 views
5

Attualmente sto cercando di scalare gevent-socketio tra più lavoratori con il server gunicorn utilizzando il lavoratore socketio.sgunicorn.GeventSocketIOWorker. Sto usando websocket quando esiste altrimenti sto forzando il polling XHR (per IE ecc.).lavoratori multipli con gevent-socketio non riesce con il trasporto XHR-polling a causa di sessioni

Il polling XHR richiede una sessione per tenere traccia dei seguenti sondaggi ma non appena passo da uno a due o più lavoratori le richieste iniziano a espandersi tra loro, il che significa che lo stato viene perso e tutto si interrompe.

penso che le seguenti righe di codice è rilevante: https://github.com/abourget/gevent-socketio/blob/master/socketio/handler.py#L104-106 suppongo ho bisogno di qualche altro motore di memorizzazione, ad esempio redis che sto usando per regolari PubSub-azioni, ma questo è profondo all'interno della libreria vera e propria.

Quindi la mia domanda è: come faccio ad andare dalla memorizzazione delle sessioni in memoria di un altro motore di back-end a livello globale nella mia applicazione (lo fa a ignorare con grazia il codice di sessione nel link qui sopra?) , senza dover modificare la libreria stessa? Something like PHP's session directives in php.ini. Suppongo che si possa sostenere che questa è una domanda Python molto generica, ma ho problemi a trovare informazioni rilevanti, e sono anche sicuro che funzionerà con questa libreria.

Oppure, in alternativa, come utilizzare il trasporto xhr-polling di gevent-socketio su diversi server e dipendenti (senza appiccicosità)?

Grazie!

+0

Solo un'idea: mantenere informazioni specifiche della sessione nei cookie? Una specie di RESTO. –

+0

@ moodh Hai mai risolto questo? Inoltre, molti lavoratori aiutano davvero? Gevent stesso svolge un ottimo lavoro gestendo già molte chiamate in un singolo ciclo di eventi. – pors

+0

No, mi sono arreso e ho iniziato a utilizzare http://pusher.com/ invece. Ci sono alcuni biglietti in gevent-socketio (https://github.com/abourget/gevent-socketio/issues/112) relativi a questo problema, ma non so fino a che punto siano arrivati. Scusa :) – moodh

risposta

3

Questa è ovviamente una limitazione di socketio. Da quello che vedo sul Web, la gestione delle sessioni viene in genere eseguita a livello di framework Web piuttosto che a server Web uno. socketio prova a farlo da solo, a livello inferiore, e lo fa in modo limitato. Immagino che gli autori pensassero che una soluzione a tutti gli effetti sarebbe un eccesso. Nel tuo caso, hanno dimostrato di essere sbagliati.

Esistono solo due modi per superare le limitazioni che richiedono modifiche logiche: applicazione di patch all'origine e patching nel runtime. Scegli quello che ti piace di più (o, beh, disgusta il minimo: ^)). Per la seconda opzione, suggerisco di sostituire request_tokens e/o il codice che lo crea con un'altra entità con la stessa interfaccia. A causa dei motivi indicati nel primo paragrafo, penso davvero che gli autori di socket possano accettare una patch di origine che consenta di utilizzare meccanismi di gestione delle sessioni esterne se ne proponi uno.

I percorsi standard per le informazioni sulla sessione sono: memoria condivisa, file, database. Ti suggerisco di cambiare la logica in modo tale che socketio usi lo stesso meccanismo del tuo framework web (o di qualsiasi altra cosa componga le tue pagine).

+0

Grazie per la tua risposta! Anche se non è una soluzione, assegnerò comunque il premio per le tue informazioni. Aspetterò una soluzione reale ma la tua risposta mi ha aiutato a capire il problema ancora di più. Sono abbastanza sicuro che finiremo per risolverlo sostituendo i token di richiesta come hai suggerito. Grazie per la tua risposta! – moodh

+0

2moodh: ho suggerito la correzione per "utilizzare lo stesso meccanismo utilizzato dal framework web". Quindi è impossibile scrivere senza sapere che cos'è questo meccanismo. –

+0

Io uso redis per mantenere le sessioni tra worker e server, niente di specifico per il pallone (il framework che sto usando). Potrebbe essere possibile lasciare che Flask usi Redis ma non l'ho ancora esaminato. :) – moodh

0

Solo un pensiero, come io sto avendo lo stesso problema; invece di lasciare la forchetta di Gunicorn (con la flag -w), forse potresti generare più processi di gunicorn su porte diverse, quindi usare nginx per bilanciarli usando uno "upstream" block with "sticky" session. Credo che sia così che l'implementazione nodejs gestisce il multiprocesso dei lavoratori quando non condivide gli stati con Redis.