Ruby on Rails: jak uruchamiać rzeczy w tle?

Kiedy nowy zasób jest tworzony i wymaga długiego przetwarzania zanim zasób będzie gotowy, Jak mogę wysłać to przetwarzanie w tło Gdzie nie zatrzyma bieżącego żądania lub innego ruchu do mojej aplikacji internetowej?

W moim modelu:

class User < ActiveRecord::Base
 after_save :background_check

 protected
 def background_check
  # check through a list of 10000000000001 mil different
  # databases that takes approx one hour :)
  if( check_for_record_in_www( self.username ) )
    # code that is run after the 1 hour process is finished.
    user.update_attribute( :has_record )
  end
 end
end
Author: Stefan, 2009-05-22

7 answers

Zdecydowanie powinieneś sprawdzić następujące Railscasts:

Wyjaśniają jak uruchamiać procesy w tle w Rails w każdy możliwy sposób (z kolejką lub bez niej ...)

 40
Author: ujh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-04 08:04:12

Uruchom oddzielny proces, który prawdopodobnie najłatwiej wykonać za pomocą system, poprzedzając 'nohup' i dołączając ' & ' na koniec przekazywanego polecenia. (Upewnij się, że polecenie jest tylko jednym argumentem łańcuchowym, a nie listą argumentów.)

Jest kilka powodów, dla których chcesz to zrobić w ten sposób, a nie, powiedzmy, próbować używać wątków:

  1. Wątki Ruby mogą być nieco trudne, jeśli chodzi o robienie I / O; musisz uważać, że niektóre rzeczy, które robisz, nie powodują całego proces do zablokowania.

  2. Jeśli uruchomisz program o innej nazwie, łatwo go zidentyfikować w "ps", więc nie pomyślisz przypadkowo, że jest to FastCGI back-end gone wild lub coś takiego I go Zabij.

Naprawdę, proces, który rozpoczniesz powinien być "deamonizowany", zobacz klasę Daemonize, Aby uzyskać pomoc.

 7
Author: Curt J. Sampson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-22 12:44:31

Właśnie eksperymentowałem z klejnotem 'delayed_job', ponieważ działa on z platformą hostingową Heroku i był śmiesznie łatwy w konfiguracji!!

Dodaj gem do Gemfile, bundle install, rails g delayed_job, rake db:migrate Następnie uruchom obsługę kolejki z;

RAILS_ENV=production script/delayed_job start

Gdzie masz wywołanie metody, które jest Twoim długim procesem Tj

company.send_mail_to_all_users

Zmieniasz na;

company.delay.send_mail_to_all_users

Sprawdź pełne dokumenty na GitHubie: https://github.com/collectiveidea/delayed_job

 6
Author: Sujimichi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-14 17:46:15

Najlepiej używać istniejącego serwera zadań w tle,zamiast pisać własne. zazwyczaj pozwalają one przesłać zadanie i nadać mu unikalny klucz; możesz następnie użyć klucza, aby okresowo odpytywać serwer zadań o status zadania bez blokowania aplikacji webapp. Oto miłe podsumowanie z różnych opcji tam.

 2
Author: Martin DeMello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-22 12:57:44

Lubię używać backgroundrb, to miłe, że pozwala komunikować się z nim podczas długich procesów. Możesz więc mieć aktualizacje statusu w swojej aplikacji rails

 1
Author: Matthew Campbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-22 16:26:14
 1
Author: Vojto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-29 14:47:38

A co z:

def background_check
   exec("script/runner check_for_record_in_www.rb #{self.username}") if fork == nil
end

Program "check_for_record_in_www.rb " zostanie uruchomiony w innym procesie i będzie miał dostęp do ActiveRecord, będąc w stanie uzyskać dostęp do bazy danych.

 0
Author: Edu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-22 13:06:04