2011-01-12 13 views
5

hi
ho intenzione di creare un sito web di rotaie dove, dopo un po 'di input iniziale dell'utente, vengono eseguiti alcuni calcoli pesanti (tramite c-extension in ruby, utilizzerà il multithreading). poiché questi calcoli consumeranno quasi tutta la cpu-time (anche la memoria), non dovrebbe mai essere eseguito più di un calcolo alla volta. inoltre non posso usare lavori di background (asincroni) (come quelli con lavoro ritardato) in quanto i binari devono mostrare i risultati di quel calcolo e il sito dovrebbe funzionare senza javascript.
quindi suppongo di aver bisogno di un processo separato in cui tutte le istanze dei binari devono accodare le loro richieste di calcolo e attendere la risposta (forse un messaggio di errore se la coda è piena), una sorta di job manager sincrono.Gestione lavori sincroni Ruby/Rails

qualcuno sa se esiste un gemma/plugin con tale funzionalità? (nanite è sembrato piuttosto interessante per me, ma sembra essere solo asincrono, quindi le istanze di rota non saprebbero quando il calcolo è finito. È corretto?)
un'altra idea è scrivere il mio usando ruby ​​distribuito (drb), ma perché inventare di nuovo la ruota se già esiste?

qualsiasi aiuto sarebbe apprezzato!

MODIFICA: a causa dei suggerimenti di zaius penso che sarò in grado di farlo in modo asincrono, quindi ho intenzione di provare resque.

risposta

5

Ruby ha mutex/semafori.

È possibile utilizzare un semaforo per assicurarsi intenso processo solo una risorsa sta accadendo allo stesso tempo.

Tuttavia, l'idea di bloccare un processo di front-end, mentre altri compiti finire non mi sembra giusto per me.Se lo facessi, userei un lavoratore in background e poi userei una pagina (o un iframe) con il meta tag refresh per controllare continuamente i progressi.

In questo modo, è possibile utilizzare lo stesso codice per sia Javascript abilitato e clienti disabili. E i thread delle tue app Web non stanno bloccando.

+0

quella cosa di metarefresh sarebbe possibile, ma avendo l'utente di ricaricare manualmente la pagina se il calcolo non è finito dopo l'aggiornamento non è troppo userfriendly nei miei occhi. non mi aspetto troppe richieste allo stesso tempo, quindi bloccare i thread Web non è una grande preoccupazione. ma hai ragione, non è un bel modo per farlo. – user573335

+0

Puoi eseguire il meta refresh tutte le volte che vuoi, se il lavoro non è terminato dopo il primo aggiornamento, mostrare loro la stessa pagina di aggiornamento e mostrare la pagina finale solo dopo aver completato il lavoro. – zaius

+0

beh, sono un po 'titubante, ma più ci penso più sembra la soluzione migliore per farlo in modo asincrono, almeno nel lungo periodo. ci sono code di lavoro che posso chiedere sulla durata dell'attività prevista (da un thread Web) e che può restituire un messaggio di errore al thread Web se ci sono troppi lavori in coda? – user573335

1

Se si dispone di un processo separato, allora si ha un processo in background ... quindi o si può avere o non puoi ...

Quello che ho fatto è avere il sito web scrivere i params richiesta in un database. Quindi un processo separato cerca richieste in sospeso nel database utilizzando la gemma daemons. Fa il lavoro e scrive i risultati nel database.

Il sito Web esegue il polling del database finché i risultati non sono pronti e quindi li visualizza.

Sebbene io usi javascript per farlo eseguire il polling.

Se davvero non si può usare javascript, sembra che sia necessario eseguire il lavoro nel thread di richiesta Web o fare in modo che il thread attenda il completamento del thread in background.

Per fare in modo che il thread della richiesta Web sia in attesa, è sufficiente eseguire un ciclo al suo interno, controllando il database fino a quando non viene salvato di nuovo la risposta. Una volta lì, puoi completare la discussione.

HTH, Chris

+0

ok, sai come posso fare in modo che il thread di richiesta Web termini il completamento del lavoro in background? poiché il thread web reuest non può generare il thread in background, non so come farlo. – user573335