Motore di pianificazione delle attività basato sul tempo

0

Sto lavorando a un'applicazione a livello aziendale. Ho una tabella degli eventi nel database. Devo aggiornare gli stati dei miei eventi nel database con una data e un'ora precise . Ci possono essere ritardi di 200 millisecondi max. Dal momento che la mia tabella degli eventi crescerà nel tempo, penso che il polling a lungo potrebbe essere un problema di prestazioni. Nella mia applicazione, che è l'API web net.core, voglio costruire una struttura che accetti ScheduledTask e in qualche modo dorme fino al prossimo TimeToExecute tempo a venire.

public class ScheduledTask
{
    public string CurrentState {get; set;}
    public string NextState {get; set;}
    public DateTime TimeToExecute {get; set;}
}

Quindi per superare la mia situazione vorrei usare;

  1. IHostedService; Con questo approccio, non ho bisogno di strumenti di terze parti. Posso iniettare l'IHostedService e usarlo. Posso controllare l'elenco ogni 150 ms ed eseguire il processo di aggiornamento in modo asincrono.

  2. HangFire; Come ho cercato, questo strumento funziona come IHostedService più o meno.

La mia domanda è quando la mia tabella degli eventi cresce e il numero di eventi aumenta (come 500 al minuto) ho altre opzioni di architettura oltre alle opzioni precedenti?

    
posta Progressive 25.09.2018 - 20:59
fonte

1 risposta

1

Provare a fare questo con qualsiasi tipo di processo leggero (processi asincroni, thread o qualsiasi altra cosa del genere) è una ricetta per il fallimento, a meno che tu non sia in un ambiente che ti dà garanzie rigide su quando il codice verrà eseguito. Inoltre, non aiuta che se il tuo programma muore e venga riavviato, qualsiasi aggiornamento dello stato in sospeso andrà perso a meno che tu non abbia un modo per ricostituirli e fare aggiornamenti che dovrebbero essere accaduti mentre il programma non era in esecuzione.

L'avviso preliminare che ricevi di un nuovo stato e quando ha effetto sono i dati e quale modo migliore di gestirli rispetto a metterli nel database? Dopotutto, stavi per fare una transazione per aggiornare lo stato comunque una volta che il tuo LWP aveva deciso che era ora. In questo modo si ottiene tutta l'ACIDity che il database ha da offrire e si ridimensionerà a qualsiasi database possa essere archiviato piuttosto che al numero di lavori che l'ambiente LWP in uso può raccogliere.

Per fare ciò è necessario interrompere lo stato degli eventi in una tabella separata che elenca gli intervalli di tempo e quale stato è in vigore in ognuno di essi.

Questo esempio è nominalmente PostgreSQL, ma puoi fare l'equivalente in qualsiasi database relazionale:

CREATE TABLE event (
    id BIGSERIAL PRIMARY KEY,
    -- All other columns except the status
);

CREATE TABLE event_status (
    event BIGINT REFERENCES events(id),  -- Which event
    times TSTZRANGE,    -- Range of times this status is valid
    status INTEGER      -- The status (doesn't have to be INTEGER)
);

Questa è la struttura della tabella. * Devi impostare vincoli e trigger per assicurarti che le righe in event_status per un dato evento esprimano un intervallo di tempo contiguo che copre l'alba del tempo all'infinito e quell'inserimento di una nuova riga regola correttamente gli orari finali delle righe circostanti.

Con questo, ottenere lo stato corrente è un JOIN delle due tabelle che elimina le righe che non sono più in vigore o non hanno ancora effetto. Funziona bene in una vista:

CREATE VIEW event_current_status AS
    SELECT event.*, event_status.status
    FROM event JOIN event_status ON event_status.event = event.id
    -- The && operator means containment, i.e., the current time
    -- falls within the range of the 'times' column.
    WHERE event_status.times && now()
    ;

Indicato correttamente ( event e times nello stesso indice su event_status dovrebbe fare), non dovresti avere problemi di rendimento.

* Hai menzionato in un commento che questa informazione è disponibile altrove nel database; Sto per salutarlo a mano per ora. Detto questo, potrebbe essere una buona idea investigare il merito di estrarlo direttamente dalle tabelle in cui è originato invece di avere una tabella di stato duplicata. Ci sono dei compromessi per entrambi che dipenderanno dalla tua situazione.

    
risposta data 25.09.2018 - 23:40
fonte

Leggi altre domande sui tag