Ho un lavoratore sidekiq che non dovrebbe richiedere più di 30 secondi, ma dopo alcuni giorni scoprirò che l'intera coda di lavoro si arresta perché tutti gli operai sono rinchiusiLavoratore sidekiq in esecuzione per migliaia di secondi anche se c'è un timeout
Ecco il mio operaio:
class MyWorker
include Sidekiq::Worker
include Sidekiq::Status::Worker
sidekiq_options queue: :my_queue, retry: 5, timeout: 4.minutes
sidekiq_retry_in do |count|
5
end
sidekiq_retries_exhausted do |msg|
store({message: "Gave up."})
end
def perform(id)
begin
Timeout::timeout(3.minutes) do
got_lock = with_semaphore("lock_#{id}") do
# DO WORK
end
end
rescue ActiveRecord::RecordNotFound => e
# Handle
rescue Timeout::Error => e
# Handle
raise e
end
end
def with_semaphore(name, &block)
Semaphore.get(name, {stale_client_timeout: 1.minute}).lock(1, &block)
end
end
E la classe del semaforo che usiamo. (Redis-semaforo gemma)
class Semaphore
def self.get(name, options = {})
Redis::Semaphore.new(name.to_sym,
:redis => Application.redis,
stale_client_timeout: options[:stale_client_timeout] || 1.hour,
)
end
end
Fondamentalmente mi fermo l'operaio e sarà stato di fatto: 10000 secondi, che il lavoratore non dovrebbe mai essere in esecuzione per.
Qualcuno ha qualche idea su come risolvere questo o quello che lo sta causando? I lavoratori sono in esecuzione su EngineYard.
Modifica: un commento aggiuntivo. Il # DO WORK ha la possibilità di attivare una funzione PostgresSQL. Ho notato nei log alcuni riferimenti a PG :: TRDeadlockDetected: ERRORE: deadlock rilevato. Questo potrebbe causare il mancato completamento dell'operatore anche con un timeout impostato?
C'è un motivo specifico per cui stai usando un blocco Semaforo all'interno metodo "eseguire" del lavoratore? Lo sto chiedendo perché sento che questo mix di Sidekiq + Locking è un po 'pericoloso. [I popoli Sidekiq raccomandano] (https://github.com/mperham/sidekiq/wiki/Best-Practices) i lavori devono essere il più possibile isolati, quindi non ci sono colli di bottiglia o potenziali deadlock che possono verificarsi bloccando le cose durante #perform –
In combinazione con sidetiq, noto che a volte lo stesso ID viene gettato sulla coda per essere elaborato, questo impedisce che venga elaborato due volte. – Geesu