Come progettare client di servizio Web resilienti?

0

Sto scrivendo un'app che dovrebbe parlare con un servizio web. Diciamo che è un'app di chat. Dovrebbe ricevere un flusso di nuovi messaggi (in modo che vengano inviati all'interfaccia il più rapidamente possibile), così come inviare i propri messaggi. Inoltre, mi piacerebbe che l'interfaccia fosse il più reattiva possibile, quindi immediatamente dopo che l'utente ha inviato un messaggio, dovrebbe essere visibile nell'elenco dei suoi messaggi. Tuttavia, la rete potrebbe essere difettosa o il server di chat potrebbe non essere disponibile. Pertanto, dopo che l'utente preme il pulsante "invia", non è garantito che il suo messaggio venga consegnato al server. L'app dovrebbe cercare di raggiungere la rete e, in caso di errore, avvisare l'utente. L'utente ha quindi la possibilità di riprovare o rinunciare del tutto.

Sto cercando di trovare un buon design per questo caso d'uso. La mia idea corrente è questa: sto implementando un oggetto proxy per il server di chat - essenzialmente, sto ri-implementando una parte del server stesso. Sto eseguendo due processi separati, uno dei quali mantiene le cronologie dei messaggi che l'utente ha con tutti i suoi colleghi. Supponiamo che l'utente abbia n peer. Quindi questo processo esegue n+2 thread, di cui:

  • n è responsabile del polling degli aggiornamenti da ciascun peer e del loro invio a una coda. Chiamiamoli Feed eventi .
  • Il thread 1 consuma quella coda ed è responsabile del mantenimento di una copia locale delle cronologie dei messaggi. anche espone un'interfaccia per inviare nuovi messaggi e iscriversi per gli aggiornamenti degli eventi. Chiamiamolo Maintainer dello stato .
  • 1 thread esegue richieste per inviare nuovi messaggi, che riceve dal Maintainer . Chiamiamolo Sender .

L'interfaccia esposta da Maintainer dello stato è alimentata da ZeroMQ . È composto da due socket: uno REP e uno PUB . In ogni iterazione del ciclo interno, questo thread recupera gli aggiornamenti dalla coda da Feed eventi , li spinge al socket PUB e controlla le nuove richieste per inviare messaggi dal socket REP . Per ogni nuova richiesta, invia l'aggiornamento alla cronologia dei messaggi che mantiene (impostando un flag maybe sent su di esso) e lo trasferisce in un'altra coda. Questa coda viene utilizzata dal Mittente . Per ogni nuovo elemento in coda, tenta di eseguire una richiesta al server di chat. In caso di successo, invia un evento che conferma il successo a una coda che viene utilizzata dal Maintainer dello stato , quindi maybe sent diventerà sent . In caso di errore, invia un evento alla stessa coda, in modo che State Maintainer cambierà maybe sent in not sent . In entrambi i casi, il risultato viene inviato attraverso il REP socket.

Il processo UI è connesso al processo proxy tramite due ZeroMQ socket. Esegue due thread. Il thread primario riceve aggiornamenti sul SUB socket e gestisce l'interfaccia utente. Parla con il thread secondario tramite due code. Quando l'utente invia un nuovo messaggio, invia tale messaggio alla coda. Il thread secondario lo preleva e lo invia al socket REQ , memorizzando un ID univoco per quella richiesta. Quando arriva la risposta (che può essere distinta dall'UID), la spinge alla seconda coda, che consente al thread dell'interfaccia utente di aggiornare l'interfaccia.

Quindi vorrei chiedere:

  • Questo approccio è buono come approccio generale alla creazione di client di servizio Web resilienti ? Avere un proxy, mantenendo un pezzo dello stato remoto, due canali per lo scambio di informazioni tra il proxy e la logica dell'app?
  • Quali sono alcune pratiche generali per risolvere questo problema? Ad esempio, ho sentito che Telegram è molto tollerante ai guasti. Vale la pena sgranocchiare il suo codice di rete ?
posta Pastafarianist 20.08.2015 - 18:33
fonte

1 risposta

1

Sembra che tu voglia spool il risultato di richieste HTTP. In effetti, potresti utilizzare un proxy HTTP con memorizzazione nella cache come calamaro (potresti usarlo, invece di codificarlo tu stesso).

Potresti utilizzare entrambe le librerie client HTTP (come libcurl ) e le librerie del server HTTP (come libonion ) nello stesso processo (ma probabilmente in thread diversi o attraverso un ciclo di eventi come libev o libevent ).

Devi ancora definire alcuni criteri di stallo (e questo sarebbe specifico per applicazione e dominio, ad esempio le previsioni meteorologiche sono sicuramente carenti in pochi giorni!), e potresti volere (forse non è una buona idea) per raggruppare i server periodicamente.

Puoi anche utilizzare (e fornire) le intestazioni HTTP% Expires e Age HTTP (nelle risposte).

    
risposta data 20.08.2015 - 22:38
fonte

Leggi altre domande sui tag