Piszę zadanie rake, które będzie wywoływane co minutę (prawdopodobnie co 30 sekund w przyszłości) przez Ilekroć i będzie ono kontaktować się z punktem końcowym API odpytywania (na użytkownika w naszej bazie danych). Oczywiście, nie jest to wydajne działanie jako pojedynczy wątek, ale czy możliwe jest wielowątkowe? Jeśli nie, czy istnieje dobra biblioteka HTTP oparta na zdarzeniach, która byłaby w stanie wykonać zadanie?Zadanie wielowątkowe rake
Odpowiedz
Piszę zadanie natarcia, które można nazwać każdy minut (ewentualnie co 30 sekund w przyszłości) za każdym razem, gdy
Strzeż Rails czas uruchamiania, może lepiej byłoby użyć rozwidlone model taki jak Resque lub Sidekiq, Rescue zapewnia https://github.com/bvandenbos/resque-scheduler, który powinien być w stanie zrobić to, czego potrzebujesz, nie mogę mówić o Sidekiq, ale jestem pewien, że ma coś podobnego dostępnego (Sidekiq jest znacznie nowszy od Resque'a)
Oczywiście nie jest to wydajne działanie jako pojedynczy wątek , ale czy można wielowątkowe? Jeśli nie, czy istnieje dobra biblioteka HTTP oparta na zdarzeniach, która byłaby w stanie wykonać zadanie?
Sugeruję obejrzysz ActiveRecord's find_each
wskazówki dotyczące podwyższenia proces finder bardziej efektywne, gdy masz swoje partie można łatwo zrobić coś przy użyciu wątków, takich jak:
#
# Find each returns 50 by default, you can pass options
# to optimize that for larger (or smaller) batch sizes
# depending on your available RAM
#
Users.find_each do |batch_of_users|
#
# Find each returns an Enumerable collection of users
# in that batch, they'll be always smaller than or
# equal to the batch size chosen in `find_each`
#
#
# We collect a bunch of new threads, one for each
# user, eac
#
batch_threads = batch_of_users.collect do |user|
#
# We pass the user to the thread, this is good
# habit for shared variables, in this case
# it doesn't make much difference
#
Thread.new(user) do |u|
#
# Do the API call here use `u` (not `user`)
# to access the user instance
#
# We shouldn't need to use an evented HTTP library
# Ruby threads will pass control when the IO happens
# control will return to the thread sometime when
# the scheduler decides, but 99% of the time
# HTTP and network IO are the best thread optimized
# thing you can do in Ruby.
#
end
end
#
# Joining threads means waiting for them to finish
# before moving onto the next batch.
#
batch_threads.map(&:join)
end
To nie rozpocznie ponad batch_size
z wątków, czekając po każdym batch_size
, aby zakończyć.
Byłoby możliwe zrobienie czegoś takiego, ale wtedy będziesz miał niekontrolowaną liczbę wątków, istnieje alternatywa, z której możesz skorzystać, staje się o wiele bardziej skomplikowana, w tym wątek i udostępniona lista zadań do wykonania. do, wysłałem to jak na Github, więc nie spamować stackoverflow: https://gist.github.com/6767fbad1f0a66fa90ac
ThreadPool wygląda świetnie! Wypróbuję to –
Dobre rzeczy, dzięki :) – Robin