Mam taki problem.
Jest aplikacja która pobiera dane z innego serwera za pomocą SOAP.
Trwa to około 30 sekund.
Mam otwarte dwie przeglądarki.
W jednej klikam wyświetl pobrane dane, dane pojawiają się natychmiast.
W drugiej klikam pobierz dane i zaczynaja się pobierać, i jak natychmiast w drugiej przeglądarce kliknę wyswietl dane,
to nie pojawiają się już natychmiast jak poprzednio, ale czekają aż zostaną pobrane dane około 30 sek. i jak dane się pobiorą w pierwszej przeglądarce to natychmiast dane się wyświetlą w drugiej przeglądarce.
Jak rozwiązać problem i zrobić aby dane wyświetlały się bez czekanania aż dane się pobiorą.
Wrzucenie akcji pobierania za pomocą SOAP do background workera to jedyna poprawna odpowiedź. Delayed_job jest chyba jednym z łatwiejszych narzędzi do tego
Temat już był wałkowany kilka razy na forum. W skrócie: odpalanie kilku procesów serwera aplikacji (thin/mongrel/unicorn) lub passenger z odpowiednimi ustawieniami lub wielowątkowe railsy (tu musiałbyś poeskperymentować) lub tak jak Tubis napisał robienie tego w tle (co jest najsensowniejszym wyjściem bo nie powinno się blokować aplikacji na tak długo).
Jeśli takie blokujące requesty są dosyć rzadkie to może wystarczy Ci to pierwsze (łatwiejsze) podejście.
Czy wykonuje zadania w tle kolejkując je czy równolegle, bo potrzebuję aby były wykonywanie równolegle.
Będzie też potrzebny pasek postępu do tego. Czym się w takim razie zainteresować deleyed_joby czy resque ?
Easier than I thought. If you decide to go this route, check out http://github.com/nzadrozny/delayed_job/tree/current_job — it sets the
current job to Delayed::Job.current so you can access it from within the
payload object. From there, you can add a progress column to your
delayed_jobs table which you can then use to poll for progress updates,
since you know the ID of the job when it is created.
The migration…
change_table :delayed_jobs do |t|
t.integer :progress
end
Inside your job…
Delayed::Job.current.update_attribute :progress, 10
In your app, as a one-off controller action…
def progress @job = Delayed::Job.find(params[:id])
render :text => @job.progress
end
Or, better yet, make a full resource out of your jobs, so you can do other
administratively useful things with them.
def show @job = Delayed::Job.find(params[:id])
respond_to do |format|
# …
format.js { render :json => @job }
end
end
I’ll be sending a pull request to Tobias, we’ll see if he thinks my tweak is
worth including in DelayedJob proper.