2010-12-29 12 views
16

Tôi có một đường ray tươi 3 ứng dụng, đây là Gemfile tôi:Delayed_job không chấp hành thực hiện phương pháp nhưng đổ công việc hàng đợi

source 'http://rubygems.org' 
gem 'rails', '3.0.0' gem 'delayed_job' 
gem 'sqlite3-ruby', :require => 'sqlite3' 

Đây là lớp đại diện cho công việc mà tôi muốn xếp hàng:

class Me < Struct.new(:something) 
    def perform 
    puts "Hello from me" 
    logger.info "Hello from me" 
    logger.debug "Hello from me" 
    raise Exception.new 
    end 
end 

Từ giao diện điều khiển không có công nhân chạy:

irb(main):002:0> Delayed::Job.enqueue Me.new(1) 
=> #<Delayed::Backend::ActiveRecord::Job id: 7, priority: 0, attempts: 0, handler: "--- !ruby/struct:Me \nsomething: 1\n", last_error: nil, run_at: "2010-12-29 07:24:11", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2010-12-29 07:24:11", updated_at: "2010-12-29 07:24:11"> 

Giống như tôi đã đề cập: không có công nhân chạy:

irb(main):003:0> Delayed::Job.all 
=> [#<Delayed::Backend::ActiveRecord::Job id: 7, priority: 0, attempts: 0, handler: "--- !ruby/struct:Me \nsomething: 1\n", last_error: nil, run_at: "2010-12-29 07:24:11", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2010-12-29 07:24:11", updated_at: "2010-12-29 07:24:11">] 

tôi bắt đầu một công nhân với script/delayed_job run

Hàng đợi được làm trống:

irb(main):006:0> Delayed::Job.all 
=> [] 

Tuy nhiên, không có gì xảy ra như là kết quả của puts, không có gì được đăng nhập từ logger cuộc gọi, và không có ngoại lệ nào được nêu ra. Tôi đánh giá cao bất kỳ trợ giúp/cái nhìn sâu sắc hoặc bất cứ điều gì để thử.

+0

Tôi có cùng một vấn đề. Bạn đã bao giờ giải quyết vấn đề này chưa? – Leddo

Trả lời

0

Tôi chỉ sao chép lớp học của bạn vào IRB và cố gắng làm Me.new.perform:

Hello from me 
NameError: undefined local variable or method `logger' for #<struct Me something=nil> 
from (irb):6:in `perform' 
from (irb):14 

Liệu lớp học của bạn có quyền truy cập vào 'logger'?

Bạn có thể thử làm một việc khác, như mở và ghi vào một tệp?

File.open("testing.txt", 'w') {|f| f.write("hello") } 

Gấu nhớ rằng lệnh 'puts' công việc lao động trì hoãn sẽ đầu ra để stdout của nó, do đó bạn sẽ không bao giờ có thể thấy điều này. Và nếu bạn muốn thực hiện bất kỳ việc ghi nhật ký nào, tôi nghĩ bạn phải tạo một cá thể Logger mới trong phương thức thực hiện của bạn để làm như vậy.

+0

Tôi đã thử xóa các cuộc gọi nhật ký và ghi tệp như bạn đã mô tả. Tôi vẫn thấy hành vi tương tự - công việc bị xóa khỏi hàng đợi nhưng tệp không được viết. – James

0

kiểm tra các bản ghi, bạn sẽ thấy một cái gì đó về các tin nhắn DelayedJob, ít nhất mà công việc được đưa ra và trạng thái thoát của nó

là những gì trong một thiết bị đầu cuối, ra mắt:

tail -f log/development.log 

sau đó thử lại từ một đường ray console để kiểm tra xem điều gì sẽ xảy ra khi thực hiện truy vấn ActiveRecord đơn giản, sau đó sử dụng DelayedJob. bạn có thể đọc những gì được đăng nhập vào thiết bị đầu cuối

cổ vũ khác, A.

12

Theo mặc định, delayed_job phá hủy công việc thất bại:

Vì vậy, bước đầu tiên là để cấu hình một initializer và tắt hành vi đó

Delayed::Worker.destroy_failed_jobs = false 

Ngoài ra, nếu bạn gặp lỗi thất bại, thì đó là lỗi thất nghiệp ngay lập tức.

Việc kích hoạt công việc này (nếu bạn chưa xóa).

Vì vậy, hãy thử thêm sau khoảng dòng 120 của worker.rb

rescue DeserializationError => error 
    say "DeserializationError: #{error.message}" 
    job.last_error = "{#{error.message}\n#{error.backtrace.join('\n')}" 
    failed(job) 

Đó là khá vô ích, nhưng ít nhất bạn sẽ biết đó là một lỗi deserialization sau đó.

Tôi đã kết thúc chỉ bằng cách sử dụng công việc w. perform() phương thức xây dựng. Đáng tin cậy hơn nhiều. Cũng nên nhớ đặt định nghĩa công việc của bạn thành một tệp riêng biệt để trình nạp lớp có thể tìm thấy nó khi nó đang chạy (thay vì chỉ nội tuyến định nghĩa lớp vào mô hình của bạn ở đâu đó).

6

Bến W là hoàn toàn đúng, Hãy chắc chắn rằng bạn có một tập tin dưới

"#{Rails.root}/config/initializers/delayed_job_worker.rb" 

này định nghĩa như thế nào người lao động nên cư xử. Người lao động sẽ lặng lẽ chỉ xóa các lỗi khác.

Khi bạn thực hiện việc này, bạn sẽ có thể tìm hiểu thêm về lỗi của mình. Đối với ví dụ của tôi, tôi đã sử dụng delay_job_mongoid, do đó, điều này đã thêm mục "last_error" (mà tôi nghĩ bạn nên có trong bảng mysql của mình cho delay_job bất kể ..)

Và khi Ben W kết luận, bạn cần đảm bảo đối tượng bạn đang tạo được biết đến với ứng dụng (hoặc cho nhân viên cho vấn đề đó). Vấn đề của tôi là tôi đang ở trong Rails Console thử nghiệm một đối tượng lớp. Người công nhân không biết lớp này, nên nó bị chặn lại.

Trong file application.rb tôi:

module TextSender 
    class Application < Rails::Application 
    require "#{Rails.root.to_s}/lib/SendTextJob.rb" 

và file lib của tôi:

class SendTextJob < Struct.new(:text, :number) 
    def perform 
    Rails.logger.info "Sending #{text} to #{number}" 
    puts "Successfully sent text" 
    end 
end 

Sau đó chạy

Delayed::Job.enqueue SendTextJob.new("Work on this text NOW, please?", "5551231234") 

Đã được xác nhận trong nhật ký của tôi/file development.log rằng điều này đã thành công. Tôi cũng đã thử nghiệm việc tạo và đối tượng (một đối tượng người dùng hoặc bất kỳ mô hình nào bạn có thể có) trong phương thức thực hiện này, và nó hoạt động.

2

Tôi gặp sự cố này và tôi nhận thấy rằng trong Rails 3 tệp trong thư mục lib/ không được tải tự động. Để chẩn đoán, tôi đã thêm:

# application.rb 
Delayed::Worker.destroy_failed_jobs = false 

như đã đề cập bởi Ben W. Điều này cho tôi biết điều gì đang xảy ra, vì tôi có thể kiểm tra last_error.

Vì vậy, để giải quyết vấn đề tự động load, tôi tìm thấy một vài câu trả lời về SO, nhưng thực chất là thêm này:

# application.rb 

# Custom directories with classes and modules you want to be autoloadable. 
# config.autoload_paths += %W(#{config.root}/extras) 
config.autoload_paths += %W(#{config.root}/lib) 
config.autoload_paths += Dir["#{config.root}/lib/**/"] 

nào được vui lòng cung cấp bởi http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/.

Tôi muốn được quan tâm để xem cách bạn có thể giải quyết vấn đề này mà không bật tự động tải cho thư mục lib. Có suy nghĩ gì không?