2012-07-19 3 views
3

나는 전자 메일을 보내기 위해 delayed_job gem을 실행중인 레일 응용 프로그램을 유지 관리하고 있습니다.delayed_job : 실패한 작업을 강제로 처리하는 방법

지연된 모든 작업이 지난 며칠 동안 응용 프로그램의 버그로 인해 실패한 것으로 나타났습니다. 이제 버그가 수정되었고 가능한 빨리 작업을 처리하려고하지만 실패한 시도가 너무 많아서 작업자가 거대한 지연으로 데이터베이스에서 작업을 가져옵니다.

나는 delayed_jobs 테이블을 업데이트하고 시도 횟수를 더 작은 숫자로 설정하고 run_at 속성을 현재 시간으로 설정했지만 여전히 도움이되지 않았습니다.

근로자가 어떻게 강제로 그 작업을 실행할 수 있습니까?

답변

10

당신은 수동으로 시작할 수 있습니다

Delayed::Job.all.each { |j| j.invoke_job } 

또는

Delayed::Job.all.each { |j| j.payload_object.perform } 
+0

꽤 합리적으로 들리 겠지만 지금 시도해 보겠습니다. :) –

+0

그래서 두 가지 방법을 시도했지만 아직 처리되지 않은 상태로있었습니다. 나는 그것을 레일 콘솔에서했는데, 내가 뭘 잘못하고 있는지 알았어? –

1

는 이제 버그가 수정되어 시도하고 나는 최대한 빨리 작업을 처리 할,하지만 그들은 이미 너무 많이와 입니다 시도가 실패한 후 작업자가 데이터베이스를 큰 지연을 가지고 에서 끌어옵니다.

즉, 작업이 테이블에서 삭제되지 않았기 때문에 지연된 작업에 대해 더 많은 시도가 남아 있습니다. 지연된 작업의 기본 동작은 사용 가능한 작업을 찾을 때 대기열에서 5 개의 작업을 읽는 것입니다. 코드 변경이별로없는 한 가지 방법은 대기열에서 더 많은 작업을 집어 실행하는 지연된 구성의 설정을 사용하는 것입니다. Delayed::Worker.read_ahead을 설정하여이를 구성 할 수 있습니다.

# config/initializers/delayed_job_config.rb 
Delayed::Worker.destroy_failed_jobs = false 
Delayed::Worker.read_ahead = 10 

Delayed::Worker.destroy_failed_jobs

는 구성 항목 인 최대 시도 후 작업의 삭제를 방지 할 수 있습니다.

지연된 작업은 데이터베이스에서 5 초마다 사용 가능한 작업을 확인하고 5 + N ** 4 초 후에 특정 작업을 시도합니다. 그래서, 만약 특정 직업이 이미 24 번 실패했다면, 331781 초 후에 그 직업이 돌아올 것입니다. 즉, 잘못하지 않으면 대략 3 일 후에.

+0

조언 해 주셔서 감사합니다. 나는 이미 그 일을 겪었지만 내 문제를 해결하지 못한다. 내 목표는 다음에 예정된 실행 전에 강제로 실행하는 것이었다. –

3

좋아, 결국 알았어!

트릭은 실제로 run_at 속성을 현재 시간으로 업데이트했지만 응용 프로그램의 현재는 데이터베이스의 3 시간 후였습니다.

지금 (3) 시간 간격으로 설정하면 모든 작업이 처리됩니다.

편집 :

@rodzyn, 나는 당신의 제안을 시도했습니다,하지만 여전히 작동되지 수 : 기존의 답변

[20] pry(main)> Delayed::Job.all.size 
    Delayed::Backend::ActiveRecord::Job Load (0.6ms) SELECT "delayed_jobs".* FROM "delayed_jobs" 
=> 1 
[21] pry(main)> Delayed::Job.first.invoke_job 
    Delayed::Backend::ActiveRecord::Job Load (0.5ms) SELECT "delayed_jobs".* FROM "delayed_jobs" LIMIT 1 
    Order Load (0.4ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = $1 LIMIT 1 [["id", "328"]] 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1 
=> nil 
[22] pry(main)> Delayed::Job.all.size 
    Delayed::Backend::ActiveRecord::Job Load (0.6ms) SELECT "delayed_jobs".* FROM "delayed_jobs" 
=> 1 
[23] pry(main)> 
+4

이 답변이 실제로 솔루션으로 제안하는 내용을 말하기는 어렵습니다. 필자는 실패한 작업을 다시 처리하고 성공하면 삭제할 루프를 다음과 같이 업데이트합니다. 'Delayed :: Job.where ("failed_at is not null"). each do | dj | dj.run_at = Time.now; dj.last_error = nil; dj.failed_at = nil; dj.save! end' – steakchaser

+0

@steakchaser에 동의합니다.이 답변에는 솔루션에 대한 정보가 충분하지 않습니다. 오래 전 이었지만 상황을 잘 기억하지 못합니다. 선택을 취소하고 승인 된 답변없이 질문을 남깁니다. –

2

없음이 정확히 권리가 없다, 그래서 나는이 추가 이리.하나는 "failed_at"또는 시도 필드가 실행에서 작업을 유지할 수 있습니다

-> rails db 
development# update delayed_jobs set run_at = now() - interval '3 hours', attempts = 0, failed_at = null; 
UPDATE 30 
development# \q 

-> rake jobs:workoff # a good one to use, because it will return immediately if no jobs are found 

: 레일 DB 콘솔을 통해 있도록

마법, 이러한 작업은 정말 실패하지 않는 것을 지연 작업을 설득하는 것입니다.

관련 문제