Come serializzare periodicamente lo stato e deserializzazione dell'oggetto sull'inizializzazione in Python?

0

Stiamo progettando un'applicazione che dovrebbe monitorare un sistema per determinati eventi, inviare le parti interessate via e-mail per richiedere loro di intervenire quando pertinente e analizzare le loro risposte.

L'applicazione è composta da diversi thread che gestiscono parti separate (una per monitorare lo stato e l'invio di e-mail, un'altra per analizzare le risposte e aggiornare lo stato, ecc.).

Il flusso dell'applicazione dipende da diversi flag che vogliamo serializzare periodicamente e se l'applicazione fallisce, all'avvio è necessario caricare quei flag serializzati o se non viene trovato alcun file serializzato, per inizializzarli su un valore predefinito.

Come possiamo ottenere il massimo? Abbiamo lavorato su idee diverse, come ad esempio:

  • sovrascrive @property di Python e getter per salvare / caricare automaticamente quei flag ogni volta che vengono richiesti / modificati

  • con un thread separato che serializza quei flag abbastanza spesso (come ogni minuto)

  • ogni thread ha cura di serializzare i flag che dipende da

Ciò che vogliamo evitare è un caso in cui il sistema intraprende un'azione, imposta alcuni flag come risultato e poi si blocca prima che tali modifiche siano serializzate.

Non possiamo usare un database e quindi ci siamo basati su cPickle come protocollo di serializzazione.

Un altro problema derivante dal problema precedente è se tali flag devono essere mantenuti centralmente in un oggetto o distribuiti tra i diversi componenti che si basano su di essi.

    
posta Nobilis 09.12.2015 - 10:55
fonte

1 risposta

1

Utilizzerei un thread "stato risparmiatore" separato che riceve i valori flag dai thread worker tramite una coda .

Il thread dello stato saver mantiene l'immagine completa dei flag per tutti i thread, inizialmente caricati dalla memoria o inviati da thread di lavoro.

Quando un nuovo messaggio arriva tramite una coda con un nuovo sottoinsieme di flag di un worker thread, il thread del risparmiatore aggiorna lo stato flag consolidato e lo scrive in un nuovo file. Quindi è possibile rinominare atomicamente il nuovo file nel nome del file canonico se si desidera solo un'istantanea o rimuovere un vecchio file se si desidera conservare diverse istantanee più recenti.

Tutti i thread worker scriverebbero i loro aggiornamenti flag sulla stessa coda, probabilmente come semplici {flag_name: value} dicts. La coda avrà una dimensione del buffer ragionevolmente grande, consentendo a ciascun thread di scrivere i propri aggiornamenti 2-3 volte, in modo che una serie di modifiche, ad es. su stratup, non farà aspettare troppo i lavoratori.

Un thread di lavoro dovrebbe pubblicare i flag su ogni evento di cambio flag, molto probabilmente tramite put_nowait . Se l'invio di un messaggio fallisce perché la coda è piena, il thread worker probabilmente dovrebbe solo registrare questo evento e procedere, e alla fine dovresti riavviare il tutto con una dimensione di coda più grande.

Il thread del risparmiatore dormirà per lo più in% chiamate% di%, forse con un timeout ragionevole per consentirgli di scrivere periodicamente un messaggio "Sono vivo" nel registro o qualcosa del genere. Dovrebbe cercare di ottenere più messaggi utilizzando Queue.get(True) e fino a quando non riceve un'eccezione get_nowait , scrivi lo stato, quindi vai di nuovo al blocco Empty .

A proposito, probabilmente non sarai bloccato con la serializzazione dei pickle; puoi ad es. usa JSON che è più facile da ispezionare se necessario.

    
risposta data 09.12.2015 - 18:11
fonte

Leggi altre domande sui tag