Mi trovo ad affrontare l'implementazione di interfacce per alcuni sistemi piuttosto arcaici, per la gestione di depositi online su conti a valore memorizzato (si pensi agli account delle carte del campus per gli studenti).
Ecco il mio dilemma: la fase 1 del processo prevede il trasferimento dell'utente a un sito di terze parti per la transazione con carta di credito, come PayPal vecchia scuola. La fase 2 prevede l'utilizzo di un protocollo proprietario per la comunicazione con un sistema legacy per lo svolgimento del deposito effettivo.
Il secondo passo richiede che ogni transazione abbia un numero di sequenza univoco e che i seqnum delle richieste siano in ordine. Dato che registriamo ogni transazione in Postgres, il mio primo pensiero è stato quello di prendere un numero da una sequenza nel DB, garantendo l'unicità. Ma dal momento che abbiamo a che fare con richieste web che potrebbero arrivare quasi contemporaneamente, e dal momento che la latenza con il ritorno dal processore di pagamento off-ste è fuori dal nostro controllo, c'è sempre la possibilità di una condizione di competizione nell'ordine delle richieste passate indietro al sistema proprietario e se i seqnum sono fuori servizio, la richiesta fallisce silenziosamente (brillante, giusto?).
Ho pensato di accodare le richieste in Redis e di utilizzare i dipendenti di Resque per elaborarle (singolo lavoratore, singolo processo, quindi sono elaborate in ordine), ma dobbiamo essere in grado di fornire al feedback dell'utente se la transazione è stata elaborato correttamente, quindi mi sembra meno fattibile.
Ho provato a fare in modo che questa applicazione gestisca bene la concorrenza (il più possibile per un'app Ruby on Rails), ma ora siamo in una situazione in cui dobbiamo interagire con un sistema progettato per essere un singolo processo , single threaded e sequential. Se almeno forniva un errore "fuori servizio", potevo semplicemente incrementare (o togliere il valore successivo dalla sequenza), ma è progettato per fallire silenziosamente in caso di QUALSIASI errore. Stiamo gestendo i timeout in un modo che blocca su I / O, ma poiché l'applicazione utilizza più worker (Unicorn), non è una garanzia.
Qualsiasi idea / suggerimento sarebbe apprezzato.