หากคุณกำลังดูสิ่งนี้ที่ https://github.com/collectiveidea/delayed_job คุณกำลังอ่านเอกสารสำหรับสาขาหลัก ดูเอกสารสำหรับรุ่นล่าสุด (4.1.13)
ล่าช้า :: Job (หรือ DJ) ห่อหุ้มรูปแบบทั่วไปของการทำงานแบบอะซิงโครนัสในพื้นหลัง
มันเป็นการสกัดโดยตรงจาก Shopify ที่ตารางงานรับผิดชอบงานหลักมากมาย ในบรรดางานเหล่านั้นคือ:
การส่งจดหมายข่าวขนาดใหญ่
การปรับขนาดภาพ
ดาวน์โหลด http
อัปเดตคอลเลกชันอัจฉริยะ
การอัปเดต SOLR เซิร์ฟเวอร์การค้นหาของเราหลังจากเปลี่ยนผลิตภัณฑ์
นำเข้าแบทช์
ตรวจสอบสแปม
ติดตามเราบน Twitter เพื่อรับการอัปเดตและประกาศเกี่ยวกับรุ่นใหม่
ล่าช้า _job 3.0.0 รองรับราง 3.0+ เท่านั้น
ล่าช้า _job รองรับหลายแบ็กเอนด์สำหรับการจัดเก็บคิวงาน ดูวิกิสำหรับแบ็กเอนด์อื่น ๆ
หากคุณวางแผนที่จะใช้ delayed_job ด้วยการบันทึกที่ใช้งานอยู่ให้เพิ่ม delayed_job_active_record
ไปยัง Gemfile
ของคุณ
gem 'delayed_job_active_record'
หากคุณวางแผนที่จะใช้ delayed_job กับ mongoid ให้เพิ่ม delayed_job_mongoid
ลงใน Gemfile
ของคุณ
gem 'delayed_job_mongoid'
Run bundle install
เพื่อติดตั้งอัญมณีแบ็กเอนด์และล่าช้า _job
แบ็กเอนด์ที่ใช้งานอยู่ต้องใช้ตารางงาน คุณสามารถสร้างตารางนั้นได้โดยเรียกใช้คำสั่งต่อไปนี้:
rails generate delayed_job:active_record rake db:migrate
สำหรับราง 4.2+ ดูด้านล่าง
ในโหมดการพัฒนาหากคุณใช้ Rails 3.1+ รหัสแอปพลิเคชันของคุณจะโหลดใหม่ทุก ๆ 100 งานโดยอัตโนมัติหรือเมื่อคิวเสร็จสิ้น คุณไม่จำเป็นต้องรีสตาร์ทงานล่าช้าทุกครั้งที่คุณอัปเดตรหัสในการพัฒนา
ใน Rails 4.2+ ตั้งค่า queue_adapter ใน config/application.rb
config.active_job.queue_adapter =: delayed_job
ดูคู่มือ Rails สำหรับรายละเอียดเพิ่มเติม
หากคุณใช้อัญมณี protected_attributes มันจะต้องปรากฏขึ้นก่อนที่จะล่าช้า _job ใน gemfile ของคุณ หากงานของคุณล้มเหลวด้วย:
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "handler" violates not-null constraint
จากนั้นนี่คือการแก้ไขที่คุณกำลังมองหา
งานล่าช้า 3.0.0 แนะนำคอลัมน์ใหม่ไปยังตารางล่าช้า _jobs
หากคุณอัพเกรดจากงานล่าช้า 2.x ให้เรียกใช้เครื่องกำเนิดอัพเกรดเพื่อสร้างการย้ายถิ่นเพื่อเพิ่มคอลัมน์
rails generate delayed_job:upgrade rake db:migrate
โทร .delay.method(params)
บนวัตถุใด ๆ และจะถูกประมวลผลในพื้นหลัง
# โดยไม่ล่าช้า [email protected]! (@อุปกรณ์)# ด้วย [email protected]! (@อุปกรณ์)
หากวิธีการควรทำงานในพื้นหลังคุณสามารถโทร #handle_asynchronously
หลังจากการประกาศวิธีการ:
อุปกรณ์ชั้นเรียน def ส่งมอบ# วิธีการทำงานยาว จบ handle_asynchronously: deliveredDevice = device.newdevice.deliver
#handle_asynchronously
และ #delay
ใช้พารามิเตอร์เหล่านี้:
:priority
(หมายเลข): ตัวเลขที่ต่ำกว่าทำงานก่อน; ค่าเริ่มต้นคือ 0 แต่สามารถกำหนดค่าใหม่ได้ (ดูด้านล่าง)
:run_at
(เวลา): ทำงานหลังจากเวลานี้ (อาจจะเป็นในอนาคต)
:queue
(สตริง): ชื่อคิวที่จะใส่งานนี้ในทางเลือกสำหรับลำดับความสำคัญ (ดูด้านล่าง)
พารามิเตอร์เหล่านี้สามารถเป็นวัตถุ PROC ช่วยให้การประเมินค่าเวลาเรียกค่าของค่า
ตัวอย่างเช่น:
Longtasks ชั้นเรียน def send_mailer# รหัสอื่น ๆ จบ handle_asynchronously: send_mailer ,: priority => 20 def in_the_future# รหัสอื่น ๆ จบ # 5. minutes.from_now จะได้รับการประเมินเมื่อเรียกว่า in_the_future handle_asynchronously: in_the_future ,: run_at => proc.new {5.minutes.from_now} def self.when_to_run2.hours.from_now จบ ชั้นเรียน << selfdef call_a_class_method # บางส่วน codeendhandle_asynchronously: call_a_class_method ,: run_at => proc.new {เมื่อ _to_run} จบ attr_reader: how_important def call_an_instance_method# รหัสอื่น ๆ จบ handle_asynchronously: call_an_instance_method ,: priority => proc.new {| i | i.how_important} สิ้นสุด
หากคุณต้องการเรียกใช้วิธี handle_asynchronously
'd โดยไม่ล่าช้างานเช่นในขณะที่การดีบักบางอย่างที่คอนโซลเพียงเพิ่ม _without_delay
ลงในชื่อวิธี ตัวอย่างเช่นหากวิธีดั้งเดิมของคุณคือ foo
ให้โทรหา foo_without_delay
งานล่าช้าใช้ไวยากรณ์พิเศษสำหรับจดหมายรถไฟ อย่าเรียกวิธี .deliver
เมื่อใช้ .delay
# โดยไม่ล่าช้า _jobnotifier.signup (@User) .deliver# ด้วย delayed_jobnotifier.delay.signup (@user)# delayed_job ทำงานที่ timenotifier เฉพาะ ,. with method ต้องเรียกก่อน. delay methodnotifier.with (foo: 1, bar: 2) .delay.signup (@user)
นอกจากนี้คุณยังอาจต้องการพิจารณาใช้งานที่ใช้งานกับ Action Mailer ซึ่งให้ไวยากรณ์ .deliver_later
ที่สะดวกซึ่งส่งต่อไปยังงานล่าช้าที่อยู่ภายใต้ฮูด
DJ 3 แนะนำรูปแบบ Resque ชื่อคิวในขณะที่ยังคงรักษาความสำคัญสไตล์ดีเจ เป้าหมายคือการจัดเตรียมระบบสำหรับการจัดกลุ่มงานที่จะทำงานโดยกลุ่มคนงานแยกต่างหากซึ่งอาจถูกปรับขนาดและควบคุมเป็นรายบุคคล
งานสามารถกำหนดให้คิวได้โดยการตั้งค่าตัวเลือก queue
:
Object.delay (: queue => 'การติดตาม'). methoddelayed :: job.enqueue Job ,: queue => 'tracking'handle_asynchronously: tweet_later ,: queue =>' ทวีต '
คุณสามารถกำหนดค่าลำดับความสำคัญเริ่มต้นสำหรับคิวชื่อ:
ล่าช้า :: worker.queue_attributes = { High_priority: {ลำดับความสำคัญ: -10} low_priority: {ลำดับความสำคัญ: 10}}
ลำดับความสำคัญของคิวที่กำหนดค่าอาจถูกครอบงำโดยการส่งลำดับความสำคัญไปยังวิธีการหน่วงเวลา
Object.delay (: queue => 'high_priority', ลำดับความสำคัญ: 0). method
คุณสามารถเริ่มกระบวนการเพื่อทำงานคิวบางอย่างด้วยตัวเลือก queue
และ queues
ที่กำหนดไว้ด้านล่าง กระบวนการเริ่มต้นโดยไม่ระบุคิวจะทำงานจากคิว ใด ๆ หากต้องการมีกระบวนการอย่างมีประสิทธิภาพที่เรียกใช้งานที่ไม่ได้ระบุคิวให้ตั้งชื่อคิวเริ่มต้นด้วย Delayed::Worker.default_queue_name
และให้กระบวนการรันคิวนั้น
script/delayed_job
สามารถใช้ในการจัดการกระบวนการพื้นหลังซึ่งจะเริ่มทำงานกับงาน
ในการทำเช่นนั้นให้เพิ่ม gem "daemons"
ลงใน Gemfile
ของคุณและตรวจสอบให้แน่ใจว่าคุณเรียกใช้ rails generate delayed_job
จากนั้นคุณสามารถทำสิ่งต่อไปนี้:
RAILS_ENV=production script/delayed_job start RAILS_ENV=production script/delayed_job stop # Runs two workers in separate processes. RAILS_ENV=production script/delayed_job -n 2 start RAILS_ENV=production script/delayed_job stop # Set the --queue or --queues option to work from a particular queue. RAILS_ENV=production script/delayed_job --queue=tracking start RAILS_ENV=production script/delayed_job --queues=mailers,tasks start # Use the --pool option to specify a worker pool. You can use this option multiple times to start different numbers of workers for different queues. # The following command will start 1 worker for the tracking queue, # 2 workers for the mailers and tasks queues, and 2 workers for any jobs: RAILS_ENV=production script/delayed_job --pool=tracking --pool=mailers,tasks:2 --pool=*:2 start # Runs all available jobs and then exits RAILS_ENV=production script/delayed_job start --exit-on-complete # or to run in the foreground RAILS_ENV=production script/delayed_job run --exit-on-complete
Rails 4: แทนที่สคริปต์/ล่าช้า _job ด้วย bin/delayed_job
คนงานสามารถทำงานบนคอมพิวเตอร์เครื่องใดก็ได้ตราบใดที่พวกเขาสามารถเข้าถึงฐานข้อมูลและนาฬิกาของพวกเขาอยู่ในการซิงค์ โปรดทราบว่าคนงานแต่ละคนจะตรวจสอบฐานข้อมูลอย่างน้อยทุก ๆ 5 วินาที
นอกจากนี้คุณยังสามารถเรียกใช้ rake jobs:work
ที่จะเริ่มทำงาน คุณสามารถยกเลิกงาน Rake ด้วย CTRL-C
หากคุณต้องการทำงานและออกจากงานทั้งหมดคุณสามารถใช้ rake jobs:workoff
ทำงานคิวโดยการตั้งค่าตัวแปรสภาพแวดล้อม QUEUE
หรือ QUEUES
QUEUE=tracking rake jobs:work QUEUES=mailers,tasks rake jobs:work
ไวยากรณ์ต่อไปนี้จะรีสตาร์ทงานล่าช้า:
RAILS_ENV=production script/delayed_job restart
ในการรีสตาร์ทพนักงานล่าช้าหลายคน: คนงาน:
RAILS_ENV=production script/delayed_job -n2 restart
Rails 4: แทนที่สคริปต์/ล่าช้า _job ด้วย bin/delayed_job
งานเป็นวัตถุทับทิมที่เรียบง่ายด้วยวิธีการที่เรียกว่าการดำเนินการ วัตถุใด ๆ ที่ตอบสนองต่อการดำเนินการสามารถยัดเข้าไปในตารางงาน วัตถุงานได้รับการจัดลำดับให้กับ Yaml เพื่อให้พวกเขาสามารถฟื้นคืนชีพได้ในภายหลังโดยนักวิ่งงาน
newsletterjob = struct.new (: ข้อความ ,: อีเมล) ทำ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} endenddelayed :: job.enqueue Newsletterjob.new ('Lorem ipsum ... ', cender.pluck (: อีเมล))
ในการตั้งค่าความพยายามสูงสุดต่องานที่แทนที่ความล่าช้า :: คนงาน. max_attempts คุณสามารถกำหนดวิธี max_attempts ในงาน
newsletterjob = struct.new (: ข้อความ ,: อีเมล) ทำ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} จบ def max_attempts3 จบ
ในการตั้งค่าเวลาทำงานสูงสุดต่อการทำงานที่แทนที่ความล่าช้า :: Worker.max_run_time คุณสามารถกำหนดวิธี max_run_time ในงานได้
หมายเหตุ: สิ่งนี้สามารถใช้เพื่อตั้งค่า max_run_time ที่ต่ำกว่าล่าช้า :: worker.max_run_time มิฉะนั้นการล็อคงานจะหมดอายุและคนงานคนอื่นจะเริ่มทำงานกับงานที่กำลังดำเนินการ
newsletterjob = struct.new (: ข้อความ ,: อีเมล) ทำ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} จบ def max_run_time120 # วินาที จบ
ในการตั้งค่าเริ่มต้นต่องานสำหรับการทำลายงานที่ล้มเหลวซึ่งแทนที่ความล่าช้า :: Worker.destroy_failed_jobs คุณสามารถกำหนด destion_failed_jobs ได้หรือไม่? วิธีการในงาน
newsletterjob = struct.new (: ข้อความ ,: อีเมล) ทำ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} จบ def destion_failed_jobs? false จบ
ในการตั้งค่าชื่อคิวเริ่มต้นสำหรับงานที่กำหนดเองที่แทนที่ล่าช้า :: worker.default_queue_name คุณสามารถกำหนดวิธี queue_name ในงาน
newsletterjob = struct.new (: ข้อความ ,: อีเมล) ทำ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} จบ def queue_name'newsletter_queue ' จบ
เกี่ยวกับข้อผิดพลาดงานจะถูกกำหนดอีกครั้งใน 5 วินาที + n ** 4 โดยที่ n คือจำนวนความพยายาม คุณสามารถกำหนดเมธอด reschedule_at
ของคุณเองเพื่อแทนที่พฤติกรรมเริ่มต้นนี้
newsletterjob = struct.new (: ข้อความ ,: อีเมล) ทำ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} จบ def reschedule_at (current_time, ความพยายาม) current_time + 5.Seconds จบ
คุณสามารถกำหนดตะขอในงานของคุณที่จะเรียกในขั้นตอนต่าง ๆ ในกระบวนการ:
หมายเหตุ: หากคุณใช้ ActiveJob ตะขอเหล่านี้ ไม่ สามารถใช้งานได้กับงานของคุณ คุณจะต้องใช้การโทรกลับของ ActiveJob คุณสามารถค้นหารายละเอียดได้ที่นี่
คลาส ParanoidNewsletterJob <NewsletterJob def enqueue (job) record_stat 'newsletter_job/enqueue' จบ def performemails.each {| e | newSlettermailer.deliver_text_to_email (ข้อความ, e)} จบ def ก่อน (Job) record_stat 'Newsletter_job/start' จบ def After (Job) Record_stat 'Newsletter_job/After' จบ Def Success (Job) Record_stat 'Newsletter_job/Success' จบ ข้อผิดพลาด def (งาน, ข้อยกเว้น) AirBrake.Notify (ข้อยกเว้น) จบ def failure (job) page_sysadmin_in_the_middle_of_the_night จบ
ห้องสมุดหมุนรอบตาราง _jobs ล่าช้าซึ่งมีลักษณะดังนี้:
create_table: ล่าช้า _jobs ,: force => true do | ตาราง | table.integer: ลำดับความสำคัญ,: default => 0 # อนุญาตให้งานบางอย่างข้ามไปที่ด้านหน้าของคิว Table.Integer: ความพยายาม,: default => 0 # จัดเตรียมไว้สำหรับการลองใหม่ แต่ก็ยังล้มเหลวในที่สุด table.text: handler # สตริงที่เข้ารหัส YAML ของวัตถุที่จะทำงานได้ table.text: last_error # เหตุผลสำหรับความล้มเหลวครั้งสุดท้าย (ดูหมายเหตุด้านล่าง) table.datetime: run_at # จะเรียกใช้เมื่อใด อาจเป็นเวลา zone ตอนนี้ทันทีหรือบางครั้งในอนาคต table.datetime: locked_at # ตั้งค่าเมื่อไคลเอนต์ทำงานกับวัตถุนี้ table.datetime: Failed_at # ตั้งค่าเมื่อการลองใหม่ทั้งหมดล้มเหลว (โดยค่าเริ่มต้นบันทึกจะถูกลบแทน) table.string: Locked_by # ใครทำงานกับวัตถุนี้ (ถ้าล็อค) table.string: คิว # ชื่อของคิวงานนี้อยู่ใน table.timestampsend
เกี่ยวกับข้อผิดพลาดงานจะถูกกำหนดอีกครั้งใน 5 วินาที + n ** 4 โดยที่ n คือจำนวนความพยายามหรือใช้วิธี reschedule_at
ของงาน
Worker.max_attempts
เริ่มต้น max_attempts คือ 25 หลังจากนี้งานจะถูกลบ (ค่าเริ่มต้น) หรือทิ้งไว้ในฐานข้อมูลด้วยชุด "Failed_at" ด้วยค่าเริ่มต้น 25 ครั้งการลองครั้งสุดท้ายจะเป็น 20 วันต่อมาโดยช่วงเวลาสุดท้ายเกือบ 100 ชั่วโมง
Worker.max_run_time
เริ่มต้น max_run_time คือ 4 ชั่วโมง หากงานของคุณใช้เวลานานกว่านั้นคอมพิวเตอร์เครื่องอื่นสามารถรับได้ ขึ้นอยู่กับคุณเพื่อให้แน่ใจว่างานของคุณไม่เกินเวลานี้ คุณควรตั้งค่าสิ่งนี้ให้เป็นเวลานานที่สุดที่คุณคิดว่างานจะต้องใช้
โดยค่าเริ่มต้นมันจะลบงานที่ล้มเหลว (และจะลบงานที่ประสบความสำเร็จเสมอ) หากคุณต้องการให้งานล้มเหลวตั้ง Delayed::Worker.destroy_failed_jobs = false
งานที่ล้มเหลวจะถูกทำเครื่องหมายด้วย non-null faild_at
โดยค่าเริ่มต้นงานทั้งหมดจะถูกกำหนดด้วย priority = 0
ซึ่งเป็นลำดับความสำคัญสูงสุด คุณสามารถเปลี่ยนสิ่งนี้ได้โดยการตั้ง Delayed::Worker.default_priority
เป็นอย่างอื่น ตัวเลขที่ต่ำกว่ามีลำดับความสำคัญสูงกว่า
พฤติกรรมเริ่มต้นคือการอ่าน 5 งานจากคิวเมื่อหางานที่มีอยู่ คุณสามารถกำหนดค่าสิ่งนี้ได้โดยการตั้ง Delayed::Worker.read_ahead
โดยค่าเริ่มต้นงานทั้งหมดจะถูกจัดคิวโดยไม่มีคิวชื่อ สามารถระบุคิวชื่อเริ่มต้นได้โดยใช้ Delayed::Worker.default_queue_name
หากไม่พบงานคนงานจะนอนตามระยะเวลาที่กำหนดโดยตัวเลือกการหน่วงเวลาการนอนหลับ ตั้ง Delayed::Worker.sleep_delay = 60
สำหรับเวลานอน 60 วินาที
เป็นไปได้ที่จะปิดการใช้งานงานล่าช้าเพื่อการทดสอบ ตั้ง Delayed::Worker.delay_jobs = false
เพื่อดำเนินการงานทั้งหมดแบบเรียลไทม์
หรือ Delayed::Worker.delay_jobs
สามารถเป็น proc ที่ตัดสินใจว่าจะดำเนินการงานแบบอินไลน์ตามเกณฑ์การทำงาน:
ล่าช้า :: worker.delay_jobs = -> (งาน) { Job.queue! = 'inline'}
คุณอาจต้องยกข้อยกเว้นเกี่ยวกับสัญญาณ sigterm, Delayed::Worker.raise_signal_exceptions = :term
จะทำให้คนงานเพิ่ม SignalException
ทำให้งานทำงานยกเลิกและถูกปลดล็อคซึ่งทำให้งานสำหรับคนงานคนอื่น ๆ ค่าเริ่มต้นสำหรับตัวเลือกนี้เป็นเท็จ
นี่คือตัวอย่างของการเปลี่ยนพารามิเตอร์งานใน Rails:
# config/initializers/delayed_job_config.rbdelayed :: worker.destroy_failed_jobs = falsedelayed :: worker.sleep_delay = 60delayed :: คนงาน ault_queue_name = 'default'delayed :: worker.delay_jobs =! rails.env.test? ล่าช้า :: worker.raise_signal_exceptions =: termdelayed :: worker.logger = logger.new (ไฟล์. ล่าช้า _job.log '))
คุณสามารถเรียกใช้ rake jobs:clear
เพื่อลบงานทั้งหมดในคิว
สถานที่ที่ดีในการขอความช่วยเหลือคือ:
กลุ่ม Google ที่คุณสามารถเข้าร่วมรายชื่อผู้รับจดหมายของเรา
stackoverflow