Contesto aziendale del problema
La nostra app per iphone consente agli utenti di pagare i commercianti e guadagnare premi.
Gli utenti possono anche fare cose come:
- Visualizza cronologia transazioni
- Visualizza i loro punti e i premi disponibili o richiedi i premi.
- Guadagna denaro facendo riferimento agli amici, visualizza una cronologia dei referral convertiti e non convertiti.
- Visualizza le offerte in corso presso alcuni commercianti (offerte speciali per l'happy hour, ecc.)
- Visualizza informazioni sui commercianti (posizione, ore, ecc.)
Poiché cose come offerte o premi disponibili, cronologia transazioni e referral possono cambiare in qualsiasi momento, abbiamo un classico problema di invalidazione della cache sul dispositivo dell'utente.
Soluzione corrente, insoddisfacente
La nostra attuale architettura è abbastanza standard e consiste di endpoint API come "/ commercianti", "/ ricompense", "/ transazioni", "/ offerte" e così via.
Al momento risolviamo il problema della cache stantia di:
- Polling sul server frequentemente mentre l'app è aperta (spesso ogni minuto per alcune chiamate API), nonché ogni volta che l'app riprende l'attenzione.
- Indicazione di dati potenzialmente obsoleti con testo come Ultimo aggiornamento di 3 minuti fa
Usiamo gli etags per evitare di inviare nuovamente i dati invariati intere (ad esempio, l'intero elenco dei commercianti), ma il nostro approccio attuale lascia ancora molta banda sprecata. Ad esempio, se un singolo commerciante cambia, tutti i commercianti vengono reindirizzati. Se viene aggiunta una singola nuova transazione, tutte le transazioni vengono reinviate.
In pratica, dal punto di vista dell'utente, questo di solito non è un grosso problema, visto che stiamo parlando di dimensioni di 1-200K al massimo, e in genere meno. Tuttavia, può essere un problema in aree con scarsa ricezione delle celle, una situazione che emerge abbastanza spesso da sentire lamentele.
E sul lato server, tutto questo polling crea un sacco di carico non necessario, soprattutto perché l'elaborazione e le query del database si verificano anche quando gli etags sono invariati,
Soluzioni migliori?
Stiamo riprogettando l'app e il codice del server e pensando a strategie alternative. Poiché questo è un problema abbastanza comune, mi piacerebbe sapere come gli altri lo risolvono.
Alcune idee che ho finora:
-
Per ridurre al minimo il trasferimento di dati : tieni traccia, sul server, dei dati che ogni utente ha effettivamente. Invia patch JSON solo ai dati modificati, anziché alle nuove copie di tutti i dati. Le copie dei dati di ciascun utente possono essere memorizzate in redis e scadono dopo alcuni giorni o una settimana. Ciò manterrebbe la "sessione attiva" veloce, mentre l'utente senza una cache del server memorizzata potrebbe semplicemente inviare una nuova copia di tutti i dati al momento del login dopo un periodo di sospensione (come ora). Mentre in teoria questo potrebbe funzionare, mantenendo sincronizzate le copie server e client, applicando entrambe le patch, sembra una ricca fonte di potenziali bug, anche se sto usando librerie di patch JSON controllate.
-
Per ridurre al minimo il carico del server : Stabilisci connessioni socket web con ciascun client, anziché il polling. Consentire agli eventi che modificano lo stato del cliente (ad esempio, un acquisto, una conversione di referral, un deal deal, ecc.) Spingere verso il basso i messaggi websocket, che a loro volta attivano il refresh del client. Questo potrebbe essere usato insieme all'idea 1 o al metodo attuale di invio di nuove copie di tutti i dati modificati. Anche con il metodo attuale, questo sarebbe comunque un enorme miglioramento, poiché i dati sarebbero richiesti e inviati solo quando necessario.
In questo momento, mi sto appoggiando verso 2 senza 1, poiché 1 sembra troppo potenzialmente irto di problemi. Ho alcune preoccupazioni nel fare affidamento su websocket su dispositivi mobili, ma dopo aver fatto ricerche qui, su SO e in altri luoghi, sembra che questa preoccupazione non sia valida.
Mi piacerebbe sentire altri, forse radicalmente diversi, suggerimenti per risolvere questi problemi.