Come posso garantire che un metodo venga chiamato una sola volta quando si utilizza un'API?

3

In generale, se sto usando un'API i cui metodi hanno effetti collaterali che voglio solo verificarsi una volta, come posso garantire che la mia stessa applicazione li chiami una sola volta anche se si verifica un errore prima che possa registrare una risposta?

Ad esempio, se sto chiamando un'API per l'elaborazione dei pagamenti una volta al mese per un servizio in abbonamento, come posso garantire che non effettui il double-bill se creo una nuova transazione e l'applicazione subisce un errore irreversibile prima di ottenere la risposta da quello? Sembra che la collaborazione con l'API sia una soluzione:

t = Transaction.new(user, price, etc);
if(t.persistToLocalDatabase()){ t.beginRemoteProcessing(); }

C'è un modo per risolvere questo problema nel caso in cui non ho alcun controllo sull'API e inizia l'elaborazione sulla creazione della transazione?

    
posta John Cartwright 09.04.2013 - 08:22
fonte

3 risposte

4

La prima cosa da fare è scrivere un flag su disco prima di iniziare la transazione per indicare che la transazione di questo mese è stata tentata. In questo modo non chiami mai accidentalmente l'API due volte.

In caso di qualsiasi tipo di errore, devi assicurarti che il sistema informi un utente (ad esempio, invia un'email) che può verificare lo stato della transazione e offre loro un modo per rielaborare manualmente la transazione.

Dopo alcuni mesi scoprirai che (a) Gli umani sono annoiati di essere contattati e devi ridisegnare il sistema (ad esempio, trovare un modo per automatizzare il controllo / riprovare tramite l'API) o (b) Il sistema sta andando bene e tutti sono felici. Spero (b).

    
risposta data 09.04.2013 - 08:54
fonte
6

Se stai inviando una richiesta che può fallire indistintamente prima o dopo il verificarsi degli effetti collaterali (come nel caso di qualsiasi richiesta di rete in cui una richiesta o una risposta possono perdersi), non c'è modo di garantire gli effetti si verificano esattamente una volta. Solo al massimo una volta (non si riprova) o almeno una volta (si continua a riprovare finché non si ottiene una risposta).

Per aggirare questa limitazione, è necessaria la cooperazione dal lato server, cioè il lato in cui si verificano gli effetti collaterali. Ci sono due opzioni:

  • L'operazione dovrebbe essere idempotente. Questo è se si esegue più volte, gli effetti sono gli stessi di una volta.
  • Puoi chiedere informazioni sullo stato dell'operazione separatamente.

Entrambi i casi richiedono che i dati inviati dal cliente identificano in modo univoco la transazione in qualche modo. Quindi, si generano i dati della transazione, li si mantiene in locale e si invia la richiesta. Se è idempotente, continui a riprovare finché non ricevi risposta. Se ha una query separata, ignori la risposta e fai la query, riprova la query fino a quando non ricevi risposta e riprova la richiesta mentre lo stato non viene eseguito.

Se anche l'API non supporta, l'unica possibilità, come suggerito da Graham, è di segnalare all'operatore umano l'errore di sistemare le cose con altri mezzi.

    
risposta data 09.04.2013 - 09:02
fonte
-1

Utilizzare una variabile per contrassegnare la chiamata al metodo. Controlla immediatamente e torna se il flag è impostato.

In C / C ++ puoi usare una variabile locale statica per memorizzare il flag.

    
risposta data 09.04.2013 - 08:36
fonte

Leggi altre domande sui tag