Sono davvero nel bel mezzo di prendere una decisione simile. Nel mio caso ho un servizio WCF in esecuzione in un ruolo web che dovrebbe scaricare i calcoli sui ruoli dei lavoratori. Quando il risultato è stato calcolato, il ruolo web restituirà la risposta al cliente.
La conoscenza della struttura dati di base mi dice che dovrei evitare di usare qualcosa che è stato progettato come una coda in modo non di coda. Ciò significa che una coda dovrebbe sempre essere revisionata in modo FIFO. Quindi, in pratica, se si utilizzano le code per entrambe le richieste e le risposte, i thread in attesa di restituire i dati al client dovranno attendere fino a quando il messaggio di calcolo si troverà nella "top" della coda di risposta, che non è ottimale.Se si memorizzano le risposte utilizzando le tabelle di Azure, i thread eseguono il polling per i messaggi che creano un sovraccarico non necessario
Ciò che credo sia una possibile soluzione a questo problema è l'utilizzo di una coda per le richieste. Ciò consente l'utilizzo del modello di consumatori in competizione e quindi il bilanciamento del carico. Sui messaggi inviati in questa coda si imposta correlationId property sul messaggio. Per rispondere, la parte pub/sub ("argomenti") del bus di servizio di Azure viene utilizzata insieme a correlation filter. Quando il tuo back-end ha elaborato la richiesta, ha pubblicato un risultato su "responseSubject" con la correlationId fornita nella richiesta originale. Ora questa risposta può essere recuperata dal tuo cliente chiamando CreateSubscribtion (Spiacente, non posso pubblicare più di due link apparentemente, google) usando quel filtro di correlazione, e dovrebbe ricevere una notifica quando la risposta è pubblicata. Si noti che la parte CreateSubscribtion deve essere eseguita una sola volta nel metodo OnStart. Quindi puoi eseguire un'async BeginRecieve su quella sottoscrizione e il ruolo verrà notificato nel callback specificato quando è disponibile una risposta per una sua richiesta. Il correlationId ti dirà a quale richiesta è rivolta la risposta. Quindi la tua ultima sfida è restituire questa risposta al thread che mantiene la connessione client.
Questo può essere ottenuto creando un dizionario con i valori di correlazione (probabilmente GUID) come chiave e le risposte come valore. Quando il tuo ruolo web riceve una richiesta, crea il guid, lo imposta come correlationId, lo aggiunge hashset, attiva il messaggio in coda e chiama Monitor.Wait() sull'oggetto Guid. Quindi fare in modo che il metodo di ricezione richiamato dalla sottoscrizione dell'argomento aggiunga la risposta al dizionario e quindi chiama Monitor.Notify() su quello stesso oggetto guid. Questo risveglia il thread di richiesta originale e ora puoi restituire la risposta al tuo cliente (O qualcosa.) Fondamentalmente vuoi solo che il tuo thread dorme e non consumare risorse mentre aspetti)
Questo è quello che stavo pensando. Stiamo già includendo una strategia GUID per la correlazione, ma sembra che ci sia un sacco di polling su quella coda di risposta in cui il ruolo Web attira risposte irrilevanti. Quando chiamo GetMessage() c'è un modo per rilasciarlo rapidamente nel probabile evento che non è la risposta che stavo aspettando? Oppure, in alternativa, potrei dare a ogni istanza di ruolo Web una coda dedicata. Anche allora, queste code non sono FIFO, quindi dovrei comunque verificare l'id di correlazione. Pensieri? –
Il problema è che se si dispone di più di un'istanza di webrole (o anche di richieste diff in esecuzione sullo stesso ruolo Web), esiste la possibilità che il messaggio destinato all'istanza 1 venga prelevato dall'istanza 2, che verrà controlla l'id di correlazione, renditi conto che non lo sta aspettando e devi rimetterlo in coda. Ho provato questo e non scala molto bene. L'idea del tavolo è molto meglio. – knightpfhor
Grazie per aver aggiunto questo commento. Ero preoccupato di questa cosa, considerando che IIS può elaborare molte richieste contemporaneamente nella stessa casella. –