2012-11-12 16 views
12

Ho un'applicazione ruby ​​on rails in cui sto cercando di trovare un modo per eseguire del codice ogni pochi secondi.task periodico delle rotaie

Ho trovato molte informazioni e idee utilizzando cron, o implementazioni simili a cron, ma queste sono solo accurate fino all'ultimo minuto e/o richiedono strumenti esterni. Voglio interrompere l'attività ogni 15 secondi o giù di lì, e voglio che sia completamente autonomo all'interno dell'applicazione (se l'app si ferma, le attività si fermano e nessuna configurazione esterna).

Viene utilizzato per la generazione in background di dati della cache. Ogni pochi secondi, l'attività assembla alcuni dati e quindi li archivia in una cache che viene utilizzata da tutte le richieste dei client. L'attività è piuttosto lenta, quindi è necessario eseguirla in background e non bloccare le richieste del client.

Sono abbastanza nuovo da rubino, ma ho un forte background perl, e il modo in cui risolverei questo sarebbe quello di creare un gestore di intervalli timer & che forca, esegue il codice, e quindi esce quando fatto.
Potrebbe essere ancora più semplice simulare una richiesta del client e avere la stessa forcella del controller delle guide. In questo modo potrei avviare l'attività colpendo l'URI per questo (sebbene dal momento che l'attività verrà eseguita ogni pochi secondi, dubito che ne avrò mai bisogno, ma potrebbe avere un uso futuro). Anche se sarebbe banale il semplice richiamo del controller, qualunque sia il metodo chiamato dall'utilità di pianificazione periodica (una volta che ne ho uno).

risposta

2

In generale, non esiste un modo integrato che conosca per creare un'attività periodica all'interno dell'applicazione. Rails è costruito su Rack e si aspetta di ricevere richieste http, fare qualcosa e poi tornare. Quindi devi solo gestire il compito periodico esternamente da solo.

Penso che data la frequenza necessaria per eseguire l'attività, una soluzione decente potrebbe essere semplicemente scrivere un semplice compito di rake che si interrompa per sempre e avviarlo contemporaneamente all'avvio dell'applicazione, utilizzando qualcosa come Foreman. Foreman viene spesso utilizzato in questo modo per gestire l'avvio/lo spegnimento degli utenti in background con le loro app. In produzione, potresti voler usare qualcos'altro per gestire i processi, come Monit.

+0

Alla fine ho appena creato un semplice strumento che si avvia quando viene avviata l'app per rails e viene eseguito periodicamente un elenco di attività. Ogni ciclo attraverso esso controlla se il genitore è ancora vivo e si chiude se non. – Patrick

0

Utilizzare qualcosa come un lavoro ritardato e riaccodarlo ogni tanto?

+0

Ha detto di volerlo come parte dell'applicazione e di essere vivo solo quando la sua applicazione è in esecuzione. Sembra eccessivo? – Altonymous

+0

Il kicker è che dovrebbe essere eseguito in un nuovo processo, quindi il processo Web può continuare a servire le richieste web. Quindi potresti creare il tuo server di fork personalizzato ... o semplicemente riutilizzare le librerie esistenti. – DGM

10

Io suggerirei il gioiello ogni volta https://github.com/javan/whenever

Esso consente di specificare un orario simile:

every 15.minutes do 
    MyClass.do_stuff 
end 

Non c'è cron jobs pianificazione o monkeying con servizi esterni.

+1

Devi stare attento a Whenever, dal momento che deve avviare l'istanza Rail ogni volta per un compito. C'è un ritardo tra il momento in cui l'attività è pianificata per l'avvio e quando Rail termina l'inizializzazione. – mguymon

+2

Penso che ogni volta che l'unità temporale più piccola è minuti, non si può usare '15.seconds' con essa. – t00ny

2

È possibile scrivere si possiede metodo, qualcosa come

class MyWorker 
    def self.work 
    #do you work 
    sleep 15 
    end 
end 

corsa con rails runner MyWorker.work Ci sarà un processo separato in esecuzione in background

Oppure si può usare qualcosa di simile Resque, ma questo è un approccio diverso. Funziona così: qualcosa aggiunge un'attività alla coda, nel frattempo un lavoratore sta recuperando qualsiasi lavoro che è in coda e cerca di finirlo.

Questo dipende dalle proprie esigenze.

0

Usa sottile o un altro server che utilizza eventmachine, poi basta usare i timer che fanno parte di eventmachine. Esempio: in config/application.rb

EM.add_periodic_timer(2) do 
    do_this_every_2_sec 
end 
Problemi correlati