Dato che il tuo servizio richiede molta attenzione, l'utilizzo di un proxy di memorizzazione nella cache sembra una buona idea. Ma attenzione: più si tenta di mantenere la semantica del sistema originale quando il back-end non funziona, più il sistema diventa complesso. E di solito, più sono sorprendenti le sue modalità di fallimento per l'utente finale. Entrambi questi fattori spesso motivano la decisione di adottare un semplice proxy di sola lettura.
Anche un proxy di sola lettura dovrebbe restituire un timestamp con i dati, per indicare quando i dati erano freschi. Per HTTP puoi codificare questo con IMS o un Etag; per altri sistemi dipenderà dal protocollo che stai utilizzando. Rifiutare di servire molto i dati unfresh dal proxy è una scelta che potresti non dover fare.
Nel tuo livello di applicazione, dovrai decidere cosa fare quando l'utente vuole eseguire un'azione simile a una mutazione sui dati di età T secondi.
Penso che normalmente sia meglio accettare la modifica e restituire un errore se il back-end (Cool.io) non ha elaborato la richiesta. Se si sceglie di rifiutare senza provare, si avranno problemi in cui il controllo pre-mutation trova il back-end in uno stato, ma il tentativo di applicare effettivamente la modifica lo trova in un altro - questa situazione è difficile da testare nel vostro sistema di regressione del sistema, quindi il mio consiglio è di non costruire un sistema che cerchi di farlo.
Se il back-end non può applicare la tua modifica, il tuo sistema potrebbe considerare questo errore come finale o potrebbe offrire di provare ad applicare la modifica quando il servizio ritorna.
Come ottimizzazione dell'esperienza utente, quando si sa che il proxy non è stato in grado di ottenere il servizio dal back-end, è possibile visualizzare avvisi sull'interfaccia utente, in modo che l'utente possa evitare una voce di data che richiede molto tempo per trovare il back-end non funziona.
Se offri di applicare una modifica non riuscita in un secondo momento, le modifiche che l'utente voleva applicare ma che non potevano essere applicate a breve avrebbero bisogno di essere archiviate. È possibile memorizzarli in una coda, ma come indicato da @mathew-flynn, sarà necessario gestire le modifiche in coda duplicate (forse in conflitto). Quindi probabilmente dovrai "accodare" le modifiche in modo interrogabile. Come in una tabella di database di modifiche non riconciliate. La cosa semplice da fare è rifiutare le modifiche ai dati che non sono state applicate al back-end. In caso contrario, l'impossibilità di applicare una determinata modifica al back-end potrebbe richiedere la revoca di più di una modifica a livello di utente.
Se è possibile che una modifica in coda non si applichi, è necessario fornire alcuni tipi di funzionalità in cui l'utente riconcilia le modifiche non riuscite.
Un caso particolarmente interessante è dove il backend è appena arrivato e un altro utente ha presentato una modifica in conflitto, dal vivo. Cioè, un nuovo cambiamento ha "superato" un cambiamento accodato. Si potrebbe prendere in considerazione il blocco di tutte le modifiche da parte degli utenti in caso di modifiche in attesa in coda. Un modo per ottenere questo è che tutte le modifiche, in diretta o differita, utilizzino la stessa coda. Se lo fai, sii molto sicuro che le modifiche ai problemi non possono rimanere bloccate in testa alla coda.
Come noterai da quanto sopra, tutto questo chiaramente richiede cambiamenti nella semantica dell'applicazione. Non puoi semplicemente farlo invisibilmente in un livello proxy, a meno che tu non rifiuti le mutazioni che non possono essere applicate immediatamente al back-end. E se fa la differenza per l'utente se i dati sono freschi o meno, potrebbe essere necessario avvisarli che stanno guardando i dati non aggiornati.
Hai anche chiesto in che modo i grandi servizi si occupano di questo. Uno dei modi più popolari è che i backend siano resi più chiari da user-id in modo che se una determinata parte del servizio è inattiva, solo alcuni utenti ne sono interessati. Questo è facile da fare per cose come il servire dati statici (che per la maggior parte non interessa chi sei) ma molto più difficile per i servizi in cui gli utenti hanno relazioni N-to-N (ad esempio cose come Twitter - anche se nel caso di Twitter le complessità attorno alle mutazioni fallite sono per lo più assenti).