myślę, że może być brakuje punktu posiadania pracowników w tle, w zasadzie, co próbujesz zrobić, to samozagłady. - Jeśli użytkownik przesyła formularz i umieszcza w kolejce zadanie w kontrolerze, tylko po to, aby użytkownik czekał na pracownika zarówno na początku, jak i na końcu, nie tylko dokonał dokładnie tego, co kontroler mógł wykonać sam, ale sprawił, że proces stał się o wiele bardziej skomplikowany (i ten typ funkcji nie jest wbudowany ani w resque, ani w sidekiq).
Podczas rozładunku zadania mają być przetwarzane przez kolejce chcesz powrócić odpowiedź do klienta niezwłocznie, tj
class PostsController < ApplicationController
def create
@post = Post.create(params[:post])
BackgroundBlogOperation.enque(@post.id)
respond_with(@post)
end
end
Klasa BackgroundBlogOperation byłyby następnie umieszczane w kolejce, dla pracownika, aby przejść przez i pracować. Jeśli potrzebujesz, aby pracownik BackgroundBlogOperation zrobił coś jeszcze po jego zakończeniu, możesz to zrobić, ale powinno to nastąpić w samym zadaniu, aby pracownik mógł być za to odpowiedzialny.
Jeśli próbujesz wyświetlić i ukryć spinner po utworzeniu postu, bez przeładowywania strony, po prostu wyświetl spinacz javascript przed kliknięciem przycisku submit i upewnij się, że typem zapytania jest js (add: remote = > true to form). Następnie należy utworzyć javascript odpowiedź widok, który wygląda tak:
class PostsController < ApplicationController
respond_to :js, :only => [:create]
def create
@post = Post.create(params[:post])
BackgroundBlogOperation.enque(@post.id)
respond_with(@post)
end
end
a create.js.erb, można również dołączyć wiadomość mówiąc im, że cokolwiek robisz w tle została w kolejce, jeśli jego bardziej skomplikowane niż tworzenie post lub cokolwiek innego.
$("#spinner").hide();
Teraz - Choć co pytali pierwotnie doesent bezcelowe (bo do wyświetlania i ukrywania tarczy po zakończeniu pracy wymagałoby czeka na kontrolerze, aby zakończyć operację) - Istnieją sytuacje, w których wyświetlanie klientowi, że zadanie zostało zakończone, jest użyteczne.
Najpierw określmy scenariusz, w którym przetwarzanie w tle jest rzeczywiście użyteczne. Powiedzmy, że masz przycisk, który po kliknięciu pobierze dane z jakiegoś zewnętrznego interfejsu API, a po pobraniu danych z witryny zewnętrznej wykonasz operację bazy danych na podstawie odpowiedzi. Byłby to dobry przykład wykorzystania procesu w tle. Zasadniczo w kontrolerze byś zrobił coś takiego:
class ApiController < ApplicationController
respond_to :js, :only => [:create]
def sync_tweets
TwitterApiJob.enque(current_user.twitter_username)
respond_with(message: 'Syncing Tweets')
end
end
Teraz, aby poinformować użytkownika, gdy tweets zakończeniu synchronizacji jest nieco bardziej skomplikowana, a masz 3 podstawowe opcje:
1) poinformować użytkowników za pośrednictwem poczty e-mail (najgorsza opcja imo) 2) Użyj jakiegoś serwera html5 lub serwera obsługującego WebSocket, aby uruchamiać szyny, i przesyłaj przez klienta websocket, który, choć bardzo fajny, jest w większości przypadków przesadą i poza zakresem tej odpowiedzi. Google szyny websocket naciskając, jeśli chcesz zobaczyć swoje opcje. 3) IMO najlepszym rozwiązaniem dla większości przypadków, Tworzenie modelu notifcations do obsługi wszelkiego rodzaju zgłoszeń użytkowników, aw swojej pracy, po zakończeniu pracy, zrobić coś
Notification.create(:user_id => user.id, :message => 'Sync has finished', type => 'sync_complete')
Następnie następnej stronie na żądanie użytkownika , na pasku narzędzi nagłówka lub gdziekolwiek, chciałbym zauważyć, że użytkownik ma nieprzeczytane powiadomienia, aby ostrzec użytkownika, aby go kliknął.
--- Także myślę, że we wpisie wspomniałeś, że używasz resque. Próbowałem resque i było przyzwoite, ale znalazłem to zbyt skomplikowane do debugowania w produkcji, i używało zwariowanej pamięci - radziłbym sprawdzić sidekiq, jeśli jeszcze tego nie zrobiłeś, używa redis także, ale znacznie szybciej, ponieważ używa wątki:
https://github.com/mperham/sidekiq
To jest znacznie szybsze, czystsze i łatwe do uzyskania konfiguracji, imho.
Chociaż przedstawiony przypadek użycia może nie być idealny, funkcja może być bardzo przydatna do generowania raportu na przykład. – aaandre