Ho un flusso di lavoro che comporta il risveglio ogni 30 secondi circa e il polling di un database per gli aggiornamenti, intervenire su quello, quindi tornare a dormire. Accantonando il fatto che il polling del database non scala e altre preoccupazioni simili, qual è il modo migliore per strutturare questo flusso di lavoro utilizzando Supervisori, lavoratori, Attività e così via?Elixir corretto modo OTP per strutturare un'attività a ciclo infinito
Esporrò alcune idee che ho avuto e i miei pensieri per/contro. Per favore aiutami a capire l'approccio più elisir-y. (Sono ancora molto nuovo a Elixir, btw.)
1. Infinite Loop Through Function Call
Basta mettere un semplice ciclo ricorsivo in là, in questo modo:
def do_work() do
# Check database
# Do something with result
# Sleep for a while
do_work()
end
I ho visto qualcosa di simile quando ho seguito insieme a tutorial on building a web crawler.
Una preoccupazione che ho qui è la profondità della catasta infinita dovuta alla ricorsione. Questo alla fine non causerà un overflow dello stack dal momento che ricorreremo alla fine di ogni ciclo? Questa struttura è utilizzata in the standard Elixir guide for Tasks, quindi probabilmente mi sbaglio sul problema dello stack overflow.
Aggiornamento - Come menzionato nelle risposte, tail call recursion in Elisir significa che gli overflow dello stack non sono un problema qui. I loop che si chiamano alla fine sono un modo accettato di fare loop infinito.
2. Utilizzare un task, Riavvia Ogni Tempo
L'idea di base è quella di utilizzare un compito che viene eseguito una volta e poi esce, ma accoppiarlo con un supervisore con una strategia one-to-one
riavvio, quindi diventa riavviato ogni volta che viene completato. L'attività controlla il database, dorme, quindi esce. Il Supervisore vede l'uscita e ne inizia una nuova.
Questo ha il vantaggio di vivere all'interno di un Supervisore, ma sembra un abuso del Supervisore. Viene utilizzato per il loop in aggiunta al trapping degli errori e al riavvio.
(Nota:. Probabilmente c'è qualcosa che può essere fatto con Task.Supervisor, in contrasto con il normale Supervisore e non sto solo capirla)
3. Task + Infinite Loop ricorsione
Fondamentalmente, combinare 1 e 2 in modo che sia un compito che utilizza un ciclo di ricorsione infinito. Ora è gestito da un Supervisore e si riavvierà se si è arrestato in modo anomalo, ma non si riavvia più e più volte come una normale parte del flusso di lavoro. Questo è attualmente il mio approccio preferito.
4. Altro?
La mia preoccupazione è che ci siano alcune strutture OTP fondamentali che mi mancano. Ad esempio, ho familiarità con Agent e GenServer, ma recentemente mi sono imbattuto in Task. Forse c'è un qualche tipo di Looper esattamente per questo caso, o qualche caso d'uso di Task.Supervisor che lo copre.
Sì, ho fatto questo modello esatto in pochi luoghi. Lo raccomando sicuramente se vuoi che un'attività periodica si verifichi in qualcosa che è già un GenServer – Micah