2013-02-13 37 views
5

Tôi có ứng dụng Rails trong đó tôi sử dụng delay_job. Tôi muốn phát hiện tôi có đang trong quá trình delay_job hay không; một cái gì đó nhưKiểm tra xem tôi có đang trong quá trình hoãn_job hay không

if in_delayed_job? 
    # do something only if it is a delayed_job process... 
else 
    # do something only if it is not a delayed_job process... 
end 

Nhưng tôi không thể tìm ra cách. Đây là những gì tôi đang sử dụng hiện nay:

IN_DELAYED_JOB = begin 
    basename  = File.basename $0 
    arguments  = $* 
    rake_args_regex = /\Ajobs:/ 

    (basename == 'delayed_job') || 
    (basename == 'rake' && arguments.find{ |v| v =~ rake_args_regex }) 
end 

Một giải pháp khác là, như @MrDanA nói:

$ DELAYED_JOB=true script/delayed_job start 
# And in the app: 
IN_DELAYED_JOB = ENV['DELAYED_JOB'].present? 

nhưng họ IMHO giải pháp yếu. Bất cứ ai có thể đề xuất một giải pháp tốt hơn?

+2

Đây có phải là phương pháp không? Điều gì về việc gửi cho nó một lá cờ để chỉ ra nếu công việc đang được gọi từ công việc bị trì hoãn hay không. Nó có thể chỉ mặc định là false, chỉ được thiết lập khi thực sự được gọi từ Job bị trì hoãn. Giải pháp nhanh chóng và dễ dàng nếu bạn không thể tìm thấy bất cứ điều gì khác. – MrDanA

+0

Vâng, đó là giải pháp khác (tôi nghĩ bạn có nghĩa là 'DELAYED_JOB = true script/delay_job start'), nhưng tôi nghĩ nó cũng là một giải pháp yếu, bởi vì tôi phải nhớ đặt hoặc bỏ đặt biến khi tôi khởi động ứng dụng với delay_job hoặc không phải là – mdesantis

+0

Phương pháp này có tự động chạy khi Công việc bị trì hoãn bắt đầu không? Tôi giả sử bạn đã làm một cái gì đó như thế này thay vì: 'user.delay.send_email' một nơi nào đó trong mã của bạn. Sau đó, bạn chỉ có thể thay đổi dòng đó thành 'user.delay.send_email (true)' trong đó 'true' biểu thị nó đang được gọi là một phần của công việc bị trì hoãn. – MrDanA

Trả lời

1

Cách mà tôi xử lý chúng là thông qua một nhân viên Paranoid. Tôi sử dụng delay_job để chuyển mã video đã được tải lên trang web của tôi. Trong mô hình của video, tôi có một trường được gọi là video_processing được đặt thành 0/null theo mặc định. Bất cứ khi nào video đang được chuyển mã bởi delay_job (cho dù khi tạo hoặc cập nhật tệp video), nó sẽ sử dụng các móc từ delay_job và sẽ cập nhật video_processing bất cứ khi nào công việc bắt đầu. Khi công việc hoàn tất, móc hoàn thành sẽ cập nhật các lĩnh vực để 0.

Theo quan điểm của tôi/điều khiển tôi có thể làm video.video_processing? ? "Video Transcoding in Progress" : "Video Fished Transcoding"

+0

Tôi sử dụng delay_job cho cùng một mục đích; bạn dùng gì để chuyển mã? Tôi đã viết một wrapper Ruby cho 'avconv' (http://libav.org/avconv.html) Dù sao, vấn đề của tôi là khác: Tôi muốn biết nếu quá trình của tôi là quá trình delay_job – mdesantis

+0

Tôi sử dụng' ffmpeg' để mã hóa video . Tôi đang sử dụng 'carrierwave',' carrierwave-video', 'delay_job' và' carrierwave_backgrounder' để tải lên, chuyển mã, xử lý nền và gửi tải lên bộ xử lý nền để chuyển mã. – kobaltz

+0

Tôi không biết về sự tồn tại của 'carrierwave-video', cảm ơn bạn – mdesantis

1

Có lẽ một cái gì đó như thế này. Thêm một trường để lớp học của bạn và đặt nó khi invoke bạn phương pháp mà làm tất cả công việc của bạn từ trì hoãn công việc:

class User < ActiveRecord::Base 
    attr_accessor :in_delayed_job 

    def queue_calculation_request 
    Delayed::Job.enqueue(CalculationRequest.new(self.id)) 
    end 

    def do_the_work 
    if (in_delayed_job) 
     puts "Im in delayed job" 
    else 
     puts "I was called directly" 
    end 
    end 

    class CalculationRequest < Struct.new(:id) 
    def perform 
     user = User.find(id) 
     user.in_delayed_job = true 
     user.do_the_work 
    end 

    def display_name 
     "Perform the needeful user Calculations" 
    end 
    end 
end 

Sau đây là cách nó trông giống:

Từ việc hoãn:

Worker(host:Johns-MacBook-Pro.local pid:67020)] Starting job worker 
Im in delayed job 
[Worker(host:Johns-MacBook-Pro.local pid:67020)] Perform the needeful user Calculations completed after 0.2787 
[Worker(host:Johns-MacBook-Pro.local pid:67020)] 1 jobs processed at 1.5578 j/s, 0 failed ... 

Từ giao diện điều khiển

user = User.first.do_the_work 
    User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 101]] 
I was called directly 
+0

vấn đề là tôi muốn biết nếu tôi đang trong một chương trình delay_job prooutss _outside_ method delay_job ... – mdesantis

+0

Trong do_the_work ở trên, in_delayed_job sẽ là không nếu bạn đến từ một cái gì đó khác hơn là delay_job. Bạn có thể mở rộng ý nghĩa của bạn bằng phương thức làm việc bị trì hoãn bên ngoài không? –

+0

Xin lỗi @JohnNaegle, tôi không thấy bình luận của bạn trước đây. Tôi đã sai, tôi muốn nói rằng tôi cần phải biết nếu tôi đang ở một công việc bị trì hoãn _before_ công việc được bắt đầu, đó là khi DelayedJob khởi động ứng dụng Rails, bởi vì tôi cần sử dụng nó trong bộ khởi tạo Rails. Phương pháp bạn đề xuất là chính xác, nhưng chỉ phù hợp với mã được tải sau khi bắt đầu công việc. – mdesantis

0

Làm thế nào về ENV [ 'PROC_TYPE']
Phát biểu duy nhất của Heroku ... nhưng khi bạn là một Dyno lao động, điều này được thiết lập để 'công nhân' tôi sử dụng nó như là tôi "Tôi đang ở trong một DJ"

+0

Oh ... cũng nếu bạn đã chia tay nhân viên web của bạn để bao gồm một nhân viên DJ (nguyên nhân tại sao không sử dụng nhân viên web thứ hai) ... Vâng nhân viên đó cũng xử lý các DJ và có env đặt thành "công nhân" – baash05

1

này làm việc cho tôi:

def delayed_job_worker? 
    (ENV["_"].include? "delayed_job") 
end 

Unix sẽ đặt biến môi trường "_" thành lệnh hiện tại.

Sẽ rất sai nếu bạn có một tập lệnh bin có tên "not_a_delayed_job", nhưng đừng làm vậy.

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