Penso che si può mancare il punto di avere lavoratori di fondo, in fondo, quello che si sta tentando di fare è controproducente. - Se l'utente invia il modulo e si accoda il lavoro nel controller, solo per fare in modo che l'utente attenda l'avvio e il completamento dell'operatore, non solo si è realizzato esattamente ciò che il controller avrebbe potuto fare da solo, ma si è ha reso il processo molto più complicato (e questo tipo di funzionalità non è integrato in resque o sidekiq).
Quando scarico un lavoro per essere elaborati da una coda che si desidera restituire una risposta al client immediatamente, vale a dire
class PostsController < ApplicationController
def create
@post = Post.create(params[:post])
BackgroundBlogOperation.enque(@post.id)
respond_with(@post)
end
end
La classe BackgroundBlogOperation sarebbe poi essere collocato in una coda, per un lavoratore di passare attraverso e lavorare fuori. Se è necessario che l'operatore di BackgroundBlogOperation faccia qualcos'altro dopo averlo terminato, è possibile farlo, ma ciò dovrebbe avvenire all'interno del lavoro stesso, in modo che il lavoratore possa essere responsabile di ciò.
Se si sta solo tentando di visualizzare e nascondere lo spinner dopo aver creato un post, senza ricaricare la pagina, è sufficiente visualizzare lo spinner javascript prima del clic del pulsante di invio e assicurarsi che il tipo di richiesta sia js (aggiungere: remote = > true to form). Quindi creare una vista risposta javascript che assomiglia:
class PostsController < ApplicationController
respond_to :js, :only => [:create]
def create
@post = Post.create(params[:post])
BackgroundBlogOperation.enque(@post.id)
respond_with(@post)
end
end
E il create.js.erb, potrebbe anche aggiungere un messaggio dicendo loro che tutto ciò che si sta facendo in background è stato in coda, se il suo più complesso rispetto alla creazione di un post o qualsiasi altra cosa
$("#spinner").hide();
ora - Anche se quello che stavi chiedendo originariamente doesent servire qualsiasi scopo (perché per visualizzare e nascondere la filatrice al termine del lavoro richiederebbe in attesa per il controller per completare l'azione) - Ci sono situazioni in cui è utile mostrare al cliente che il processo ha terminato l'elaborazione.
Prima consente di definire uno scenario in cui l'elaborazione in background è effettivamente utile. Diciamo che hai un pulsante che quando fai clic, inserirà i dati da qualche API esterna e, dopo aver ottenuto i dati dal sito esterno, eseguirai un'operazione di database basata sulla risposta. Questo sarebbe un buon esempio di quando utilizzare il processo in background. In sostanza nel regolatore si farebbe qualcosa di simile:
class ApiController < ApplicationController
respond_to :js, :only => [:create]
def sync_tweets
TwitterApiJob.enque(current_user.twitter_username)
respond_with(message: 'Syncing Tweets')
end
end
Ora, per informare l'utente quando i tweets hanno finito la sincronizzazione è un po 'più complicato, e si dispone di 3 opzioni di base:
1) Notifica degli utenti via email (generalmente l'opzione peggiore imo) 2) Utilizzare una sorta di server html5 o websocket rails capace di eseguire le rotaie e inviare una spinta attraverso il websocket al client, che sebbene molto interessante, è nella maggior parte dei casi eccessivo e al di fuori dell'ambito di questa risposta. Google rotaie websocket che spingono se vuoi vedere le tue opzioni. 3) IMO migliore opzione per la maggior parte dei casi, creare un modello notifcations per gestire tutti i tipi di notifiche degli utenti, e nel vostro lavoro, dopo che il lavoro è completo, fare qualcosa di simile
Notification.create(:user_id => user.id, :message => 'Sync has finished', type => 'sync_complete')
Poi, pagina seguente le richieste degli utenti , in alto nella barra degli strumenti di intestazione o dovunque, avrei un avviso che l'utente ha notifiche non lette, per avvisare l'utente di cliccarci sopra.
--- Inoltre, penso che nel tuo post hai menzionato che stai utilizzando resque. Ho provato a resque ed è stato decente, ma ho trovato che è complicato fare il debug in produzione, e ha usato una memoria pazzesca - ti consiglio di controllare sidekiq se non lo hai già fatto, usa anche i redis ma molto più velocemente in quanto usa discussioni:
https://github.com/mperham/sidekiq
è molto più veloce, più pulito e facile da ottenere l'installazione, imho.
Mentre il caso di utilizzo presentato potrebbe non essere l'ideale, la funzionalità potrebbe essere molto utile per l'esecuzione di un report, ad esempio. – aaandre