Come gestire gli eventi basati sul tempo nel back-end dell'applicazione Web?

4

Attualmente sto lavorando alla progettazione di piccoli servizi Web, e ho una funzione seguente (semplificata):

Dopo alcune azioni dell'utente, c'è un periodo di attesa (compreso tra 30 secondi e 40 ore) e dopo il suo passaggio, il server deve aggiornare la voce del database per l'attività, a meno che l'utente non la annulli durante il periodo di attesa. L'attività eseguita è abbastanza semplice, solo alcuni calcoli, ma deve essere ritardata.

E non ho idea di come farlo ...

So che una situazione simile si verifica in alcuni giochi basati su browser, in cui si aggiorna un edificio e si ottengono dei bonus dopo che è terminato, ma non sono stato in grado di trovare il modo in cui questa funzione è stata raggiunta. Quindi, la mia domanda è: esiste un metodo "all'avanguardia" per gestire tali problemi nel back-end, o qualsiasi metodo?

    
posta Wikiii122 19.08.2015 - 17:40
fonte

3 risposte

4

Puoi farlo in modi diversi. Ciò che alla fine fa dipende dallo stack sul lato server, dalle autorizzazioni sul server e dalla natura degli effetti collaterali necessari per l'evento ritardato.

Come li vedo, le tue opzioni sono:

  • Un'attività pianificata "incorporata". Se utilizzi una tecnologia di back-end simile a un servizio (come un server nodo), puoi applicare i timeout all'applicazione. E in alcuni casi, come nel caso del nodo, potresti addirittura programmare un timeout per ogni singolo evento (se risulta essere più efficiente dell'elaborazione di una coda di eventi nel tuo caso).
  • Un cron job separato, un'attività di Windows o processo, demone o servizio in background. Un cron job dovrebbe essere in grado di eseguire fino a una volta al minuto. Un'attività di Windows può essere eseguita fino a ogni 5 minuti. Un lavoro in background, un demone o un servizio può utilizzare sleeps / wait / timeouts per fare cose anche su intervalli più brevi.
  • Elaborazione degli eventi basata su client. Se non sono necessari effetti collaterali quando i dati non vengono utilizzati attivamente (ad esempio, tutti gli utenti che si preoccupano del valore sono disconnessi), puoi evitare il sovraccarico e complessità dei lavori di "manutenzione" periodici semplicemente calcolando determinati valori e / o elaborando gli eventi necessari durante le richieste dei clienti. Ad esempio, per ogni richiesta da e su UtenteX, ottieni le voci da "la coda" dove event_fire_time <= now e event_user = UserX , e "completa" quegli eventi.

In tutti gli scenari, assicurati di bloccare (con le transazioni se si utilizza un DBMS) i record che il codice evento sta elaborando.

    
risposta data 19.08.2015 - 18:52
fonte
2

Devi memorizzare le tue attività, ad esempio in una tabella db, con almeno le seguenti informazioni:

  • time_to_execute : timestamp di quando è stata impostata l'attività + ritardo in secondi
  • to_do : cose da fare (questo deve essere comprensibile dal tuo back-end)
  • executed : 1 se l'attività è già stata eseguita, altrimenti 0 (impostazione predefinita)

Quindi, è necessario un programma di pianificazione, potrebbe essere un cron , che periodicamente, ad esempio ogni minuto, richiede un endpoint nel back-end, che a sua volta interrogherà la tabella db contenente le attività pianificate. Lo pseudo-codice per questo dovrebbe essere come:

my_backend_endpoint_callback():
    for task in tasks:
        if not task.executed and time_to_execute > time.now():
            result = execute_my_task(task.to_do)
            if result == 0:
                # task was properly executed
                task.executed = 1

Puoi quindi avere un altro ciclo che cancellerà tutte le attività eseguite, a seconda se vuoi mantenere la traccia o meno.

    
risposta data 19.08.2015 - 19:50
fonte
1

Un approccio semplice consiste nell'avere una tabella delle attività in sospeso nel database.

Per creare un'attività, aggiungere una riga alla tabella che contiene il tempo di azione e qualsiasi altro dato necessario per elaborare l'attività. Si dispone di un thread in background che interroga periodicamente la tabella, esegue le azioni che sono scadute e rimuove le attività completate dalla tabella.

Non lo descriverei come "stato dell'arte", ma è un modo relativamente semplice e affidabile per fare ciò che ti serve.

Al termine di un'attività, devi avvisare gli utenti? Ciò rende le cose un po 'più complicate in quanto è necessario che tutti i client mantengano una connessione WebSocket al server, quindi è possibile inviare notifiche.

    
risposta data 19.08.2015 - 18:24
fonte

Leggi altre domande sui tag