2014-04-03 2 views
5

나는 sidekiq 작업자가 30 초를 넘겨서는 안되지만 몇 일 후에 전체 작업자 큐가 실행을 중지한다는 것을 알게 될 것입니다. 노동자들은 갇혀있다.시간 초과가 있더라도 Sidekiq 작업자가 수천 초 동안 실행 중

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 

그리고 우리가 사용하는 세마포어 클래스 :

여기 내 노동자입니다. (레디 스 - 세마포어 보석)

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 

는 기본적으로 나는 노동자가 중단 그것은 완료 상태 것이다 노동자가 결코 출마해서는 안 만초을.

누구든지이 문제를 해결하는 방법이나 원인을 알 수 있습니까? 노동자들이 EngineYard에서 뛰고 있습니다.

편집 : 추가 의견 1 개. # DO WORK는 PostgresSQL 함수를 실행할 수있는 기회를 제공합니다. 로그에서 PG :: TRDeadlockDetected에 대한 언급을 보았습니다 : ERROR : deadlock detected. 이로 인해 작업자가 제한 시간을 설정해도 완료되지 않습니까?

+0

당신이 노동자의 "수행"방법 내부 세마포어 잠금을 사용하는 이유는 어떤 특별한 이유가 있습니까? 나는 Sidekiq + Locking의 혼합이 약간 위험하다고 생각하기 때문에 이것을 묻습니다. [Sidekiq 사람들은] (https://github.com/mperham/sidekiq/wiki/Best-Practices) 작업을 최대한 격리 시켜서 #perform 중에 잠금 작업을 수행 할 때 발생할 수있는 병목 현상이나 잠재적 교착 상태가 없음 –

+0

sidetiq와 함께 처리 할 큐에 동일한 ID가 throw되는 경우가 있음을 알았습니다. 두 번 처리되지 않습니다. – Geesu

답변

1

당신이 독특한 작업 실행을 보장 할 감안할 때, 나는 sidetiq이 두 번이 플러그인 보장하지만이 같은 작업 ID를 대기열에 경우에도 모든 잠금을 제거하려고하고이 경우 Sidekiq Unique Jobs

같은 플러그인으로 작업 고유성 제어를 위임 것 대기열에 넣거나 한 번 처리됩니다.

+0

그래서 문제가 redis-semaphore라고 생각합니까? 시간 초과가 무시되는 이유는 아직도 알 수 없습니다. – Geesu

0

당신은 또한 액티브 with_lock 메커니즘을 시도 할 수 있습니다 : http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html

+0

이것이 실제로 문제의 실제 원인 일 수 있다고 생각합니다. http://blog.headius.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html – Geesu

+0

아, 그래, 그렇게 많이 보입니다. 자기 자신에게주의하고, 데이터베이스 잠금으로 시간 종료하지 마십시오. 시간 초과가 필요한 이유가 있습니까? 그 사이의 기록에 액세스 할 수 있도록 논리를 무너 뜨리는 방법이있을 수 있습니다. – lobati

+0

btw, 자신의 질문에 대답 해보십시오. – lobati