Parallelismo quando si usano le funzioni di Azure per aggiornare un documento DocumentDB

5

Sto scrivendo un'app Web che consente agli utenti di caricare annunci immobiliari. Parte di ciò che fa è consentire loro di caricare le foto della proprietà che stanno elencando.

Sto utilizzando un approccio di tipo micro-service, quindi c'è un servizio multimediale di proprietà che gestisce tutto il caricamento di media, l'interrogazione di quali supporti sono disponibili per ogni proprietà, ecc.

Tuttavia, poiché ho bisogno di ricerche rapide e visualizzazione di una pagina di proprietà senza chiamare a 7 o 8 servizi, mantengo anche una raccolta di proprietà Azure DocumentDB, in cui ogni documento contiene tutto ciò che riguarda la proprietà specifica necessaria per supportare la ricerca e l'associazione di la pagina dei dettagli della proprietà.

Fin qui tutto bene.

Ho optato per un pattern di sourcing di eventi durante il quale, quando è stata caricata una nuova foto, ho semplicemente innalzato un evento in un argomento di Azure Service Bus. C'era una sottoscrizione a questo argomento che era un trigger per una funzione di Azure che caricava il documento, lo aggiornava con i dettagli dell'immagine caricata e lo salvava.

Ha funzionato - ma poi ho un problema di parallelismo / concorrenza per cui se un utente carica 10 immagini, solleva 10 eventi sull'argomento. Con la natura delle funzioni di Azure, potrebbe generare fino a 10 processi contemporaneamente ogni volta che si consegna un messaggio.

Poiché Azure DocumentDb non supporta gli aggiornamenti di documenti parziali, la funzione di Azure procede come segue:

  • Carica il documento
  • Aggiunge un figlio alla raccolta images
  • Salva il documento

Di recente ho notato che non ricevo un aggiornamento affidabile durante il caricamento di più immagini. Forse solo 6 dei 10 mostreranno nel DocumentDb. I log della funzione mostrano che tutte e 10 le esecuzioni sono andate a buon fine, quindi posso solo supporre che sono stato vittima di esse in esecuzione in parallelo e un aggiornamento che sovrascrive un altro.

Per aggirarlo, ho fatto in modo che il servizio multimediale non aumentasse più un evento, ma aggiorna semplicemente il DocumentDb stesso. Ma non ne sono davvero contento perché non è davvero una sua responsabilità nella mia mente. Per il momento è stato risolto il problema, ma mi è piaciuto l'event-sourcing e le funzioni di Azure che aggiornano il documento come un design migliore.

Ci sono delle opzioni migliori per me? Ho considerato che avrei potuto aggiungere un documento alla raccolta DocumentDb nella funzione di Azure invece di aggiornare un "documento master", ma in tal caso significherebbe più lavoro nella pagina dei dettagli della proprietà per aggregarlo insieme.

Ho perso un trucco?

    
posta bgs264 04.03.2017 - 16:08
fonte

1 risposta

0

Quindi, la mia comprensione di Event Sourcing è che si ricrea il proprio oggetto da eventi salvati piuttosto che la deserializzazione tradizionale dello stato dell'oggetto. Sembra che tu non lo stia facendo davvero.

Perché l'ordine degli eventi è solitamente importante. Ciò richiede una qualche forma di transazione manuale, dove si assegna identificatori di eventi sequenziali, o un numero di versione e si può sapere se è accaduto un altro evento mentre si stava elaborando l'evento su cui si sta lavorando. vale a dire.

  • Carica documento
  • leggi il vecchio numero di versione / l'ultimo ID evento
  • aggiungi immagine con ID evento
  • aggiorna il numero di versione
  • sovrascrivi doc SE il numero di versione è uguale / non sono stati aggiunti altri eventi
  • SE la versione è cambiata da quando hai iniziato, ripeti l'operazione.

Ovviamente questo non funziona bene se si hanno molte collisioni mentre si ripetono sempre i passaggi. Inoltre hai ancora bisogno di una sorta di transazione supportata da DB per il passaggio finale.

Tuttavia, vedo che DocumentDb supporta le transazioni:

Does DocumentDB support ACID transactions?

Yes, DocumentDB supports cross-document transactions expressed as JavaScript stored procedures

Suggerirei di creare una semplice transazione riutilizzabile che controlli solo il numero di versione del documento come previsto. Puoi quindi usarlo con tutti i tuoi eventi.

    
risposta data 07.03.2017 - 11:25
fonte

Leggi altre domande sui tag