2012-08-13 31 views
9

Tôi có một chức năng được đánh dấu để được xử lý không đồng bộ bằng cách delayed_job:Đi qua một khối đến một delayed_job

class CapJobs 
    def execute(params, id) 
    begin 
     unless Rails.env == "test" 
     Capistrano::CLI.parse(params).execute! 
     end 
    rescue 
     site = Site.find(id) 
     site.records.create!(:date => DateTime.now, :action => "Task Failure: #{params[0]}", :type => :failure)  
     site.save 
    ensure 
     yield id 
    end 
    end 
    handle_asynchronously :execute 
end 

Khi tôi chạy chức năng này tôi vượt qua trong một khối:

capjobs = CapJobs.new 
capjobs.execute(parameters, @site.id) do |id| 
    asite = Site.find(id) 
    asite.records.create!(:date => DateTime.now, :action => "Created", :type => :init) 
    asite.status = "On Demo" 
    asite.dev = true 
    asite.save 
end 

tác phẩm này tốt khi chạy mà không có delay_job nhưng khi chạy với nó tôi nhận được lỗi sau đây

2012-08-13T09:24:36-0300: [Worker(delayed_job host:eagle pid:12089)] SitesHelper::CapJobs#execute_without_delay failed with LocalJumpError: no block given (yield) - 0 failed attempts 
2012-08-13T09:24:36-0300: [Worker(delayed_job host:eagle pid:12089)] PERMANENTLY removing SitesHelper::CapJobs#execute_without_delay because of 1 consecutive failures. 
2012-08-13T09:24:36-0300: [Worker(delayed_job host:eagle pid:12089)] 1 jobs processed at 0.0572 j/s, 1 failed ... 

Có vẻ như không nhận khối này đã được thông qua. Đây không phải là cách đúng để làm điều này hay tôi nên tìm một phương pháp khác?

Trả lời

1

Tôi đã tìm thấy phương pháp thực hiện việc này. Đó là loại hacky nhưng hoạt động tốt. Tôi tìm thấy this article mà nói về việc tạo ra một lớp SerializableProc. Nếu tôi chuyển nó đến hàm thì mọi thứ sẽ hoạt động tốt.

+2

bạn có thể xin vui lòng gửi những gì mã bạn sử dụng? – brauliobo

8

delay_job hoạt động bằng cách lưu công việc của bạn vào kho dữ liệu (thường là cơ sở dữ liệu chính) và sau đó tải công việc ra khỏi kho dữ liệu này trong quá trình nền, nơi nó được xử lý/thi hành.

Để lưu công việc vào cơ sở dữ liệu, delay_job cần bằng cách nào đó lưu phương thức nào để gọi đối tượng nào với đối số nào. Điều này được thực hiện bằng cách tuần tự hóa mọi thứ thành một chuỗi (delay_job sử dụng yaml cho điều đó). Thật không may, các khối không thể được tuần tự hóa. Vì vậy, nhân viên nền không biết về đối số khối và gọi phương thức mà không có nó. Điều này dẫn đến kết quả là LocalJumpError khi phương thức đang cố gắng mang lại khối.

0

Hầu hết mọi người coi đây là vấn đề trừu tượng.

Mã proc có thể không thay đổi từ chạy sang chạy (ngoại trừ vars) và vì vậy bạn nên làm cho mã khối thành một lớp hoặc phương pháp thể hiện. Vượt qua tên của phương pháp đó, và sau đó gọi nó trong phương thức execute của bạn, giống như

@some_data = CapJobs.send(target_method)

hoặc có lẽ-tốt hơn kể cả

@some_data = DomainSpecificModel.send(target_method)

Các vấn đề liên quan