รันบล็อกรหัสและลองใหม่เมื่อมีข้อยกเว้นเกิดขึ้น เป็นเรื่องดีเมื่อทำงานกับ WebServices Flakey (ตัวอย่าง)
มันได้รับการกำหนดค่าโดยใช้พารามิเตอร์ทางเลือกหลายอย่าง :tries , :on , :sleep , :matching , :ensure , :exception_cb , :not , :sleep_method และเรียกใช้บล็อกที่ผ่าน หากมีข้อยกเว้นเกิดขึ้นมันจะลอง (N-1) ครั้ง
หากจำนวนการลองกลับมาโดยไม่ประสบความสำเร็จข้อยกเว้นสุดท้ายจะเพิ่มขึ้น
ติดตั้งอัญมณี:
$ gem ติดตั้ง retryable
เพิ่มลงใน Gemfile ของคุณ:
อัญมณี 'retryable'
เปิด URL, ลองอีกครั้งถึงสองครั้งเมื่อ OpenURI::HTTPError เกิดขึ้น
ต้องการ "open-uri" retryable.retryable (พยายาม: 3, on: openuri :: httperror) ทำ
xml = เปิด ("http://example.com/test.xml"). readendลองบล็อกตลอดไป
# สำหรับเวอร์ชันทับทิมก่อน 1.9.2 การใช้งาน: สัญลักษณ์อนันต์แทนที่จะเป็นไปได้ # รหัสที่นี่
ทำอะไรบางอย่างลองใหม่ถึงสี่ครั้งสำหรับ ArgumentError หรือ Timeout::Error
retryable.reterable (พยายาม: 5, on: [argurterror, หมดเวลา :: ข้อผิดพลาด]) ทำ # รหัสที่นี่
ตรวจสอบให้แน่ใจว่าบล็อกของรหัสถูกดำเนินการโดยไม่คำนึงว่ามีการยกข้อยกเว้นหรือไม่ ไม่สำคัญว่าบล็อกจะออกตามปกติหรือไม่หากมีการพยายามเรียกใช้บล็อกของรหัสหรือหากถูกยกเลิกโดยข้อยกเว้นที่ไม่ถูกต้อง - :ensure บล็อกจะทำงาน
f = file.open ("testfile") uce_cb = proc do | retries | วาง "ความพยายามลองใหม่ทั้งหมด: #{retries}"
f.closeendretryable.retryable (ตรวจสอบให้แน่ใจว่า: ตรวจสอบให้แน่ใจว่า _cb) ทำ
# ประมวลผล fileendcontexts: {},
ensure: proc { },
exception_cb: proc { },
log_method: proc { },
matching: /.*/,
not: [],
on: StandardError,
sleep: 1,
sleep_method: lambda { |n| Kernel.sleep(n) },
tries: 2สามารถกำหนดค่าได้อีกครั้งเพื่อเปลี่ยนค่าเริ่มต้นเหล่านั้น:
retryable.configure do | config | config.contexts = {}
config.ensure = proc {}
config.exception_cb = proc {}
config.log_method = proc {}
config.matching = /.*/
config.not = []
config.on = StandardError
config.sleep = 1
config.sleep_method = lambda {| n | kernel.sleep (n)}
config.tries = 2endโดยค่าเริ่มต้น retryable รอหนึ่งวินาทีระหว่างการลองใหม่ คุณสามารถเปลี่ยนสิ่งนี้และจัดทำโครงการ backoff แบบเอ็กซ์โปเนนเชียลของคุณเอง
retryable.retryable (sleep: 0) {} # อย่าหยุดชั่วคราวระหว่าง retriesretryable.retryable (นอนหลับ: 10) {} # นอนสิบวินาทีระหว่าง retriesretryable.retryable (นอน: lambda {| n | 4 ** n}) {} # sleep 1, 4, 16 ฯลฯ แต่ละครั้งลองคุณยังสามารถลองใหม่ตามข้อความยกเว้น:
retryable.retryable (การจับคู่: /io timeout /) do | retries, exception | เพิ่ม "oops io หมดเวลา!" หาก retries == 0END#พารามิเตอร์การจับคู่รองรับรูปแบบอาร์เรย์เช่นกัน: retryable.retryable (การจับคู่: [/io หมดเวลา/, "io tymeout"]) ทำ | retries, ข้อยกเว้น | เพิ่ม "oops io หมดเวลา!" ถ้า retries == 0END
บล็อกของคุณถูกเรียกด้วยพารามิเตอร์เสริมสองตัว: จำนวนพยายามจนถึงตอนนี้และข้อยกเว้นล่าสุด
retryable.retryable do | retries, exception | วาง "ลอง #{retries} ล้มเหลวโดยมีข้อยกเว้น: #{Exception}" ถ้า retries> 0
# รหัสที่นี่ exception_cb = proc do | ข้อยกเว้น | # http://smartinez87.github.io/exception_notification
ExceptionNotifier.notify_exception (ข้อยกเว้น, ข้อมูล: {ข้อความ: "มันล้มเหลว"}) endretryable.retryable (exception_cb: exception_cb) ทำ
# รหัสที่นี่ # หรือแยกออกเป็น global config แทน: log_method = lambda do | retries, exception | logger.new (stdout) .debug ("[พยายาม ## {retries}] ลองใหม่เพราะ [ #{exception.class} - #{exception.message}]: #{exception.backtrace.first (5) .join (' | ')} ") endretryable.retryable (log_method: log_method, การจับคู่: /io หมดเวลา /) ทำ | retries, exception | เพิ่ม "oops io หมดเวลา!" ถ้า retries == 0END #D, [2018-09-01T18: 19: 06.093811 #22535] DEBUG-: [พยายาม #1] ลองใหม่เพราะ [RuntimeRror-OOPS IO หมดเวลา!]: (IRB #1): 6: `block in irb_binding '| /home/nikita/projects/retryable/lib/retryable.rb:73:in `retryable '| (irb#1): 6: ใน `irb_binding '| /home/nikita/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/irb/workspace.rb:85:in `eval '| /home/nikita/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/irb/workspace.rb:85:in `ประเมิน 'หากคุณต้องการใช้ตัวบันทึกดั้งเดิมของ Rails:
log_method = lambda do | retries, exception | rails.logger.debug ("[พยายาม ## {retries}] retrying เพราะ [ #{exception.class} - #{exception.message}]: #{exception.backtrace.first (5) .join ('|') }")จบ บริบทช่วยให้คุณสามารถแยกตัวเลือกการโทร Retryable.retryable เพื่อการใช้ซ้ำหรือการอ่าน
retryable.configure do | config | config.contexts [: faulthy_service] = {on: [fultyserviceetimeouterror], นอนหลับ: 10, พยายาม: 5
} endretryable.with_context (: faulthy_service) {
# รหัสที่นี่}นอกจากนี้คุณยังสามารถแทนที่ตัวเลือกที่กำหนดไว้ในบริบทของคุณ:
#: On & Sleep ที่กำหนดไว้ในบริบทก่อนหน้านี้ยังคงเป็น effectiveretry.with_context (: faulty_service, ret: 999) {
# รหัสที่นี่}retryable.enabled? => trueretryable.disableretryable.enablem
จะไม่มีการพยายามอีกต่อไปหากมีข้อยกเว้นที่ระบุไว้ใน :not ได้รับการยก มีความสำคัญกว่า :on
คลาส Myerror <StandardError; endretryable.reterable (พยายาม: 5, on: [StandardError], ไม่ใช่: [myerror]) ทำ Raise Myerror "No Retries!" สิ้นสุด
:sleep_method ที่จะใช้สิ่งนี้มีประโยชน์มากเมื่อคุณทำงานกับเซลลูลอยด์ซึ่งใช้วิธีการนอนหลับรุ่นของตัวเอง
retryable.reterable (sleep_method: celluloid.method (: sleep)) ทำ # รหัสที่นี่
ห้องสมุดนี้มีวัตถุประสงค์เพื่อสนับสนุนและทดสอบกับรุ่นทับทิมต่อไปนี้:
ทับทิม 3.3
ทับทิม 3.2
ทับทิม 3.1
ทับทิม 3.0
ทับทิม 2.7
ทับทิม 2.6
ทับทิม 2.5
ทับทิม 2.4
ทับทิม 2.3
ทับทิม 2.2
ทับทิม 2.1
ทับทิม 2.0
หมายเหตุ: หากคุณต้องการ retryable ใช้ Ruby 1.8 ให้ใช้ GEM เวอร์ชันก่อนที่จะรีลีส 3.0.0
หากสิ่งที่ไม่ได้ผลกับหนึ่งในเวอร์ชันเหล่านี้มันเป็นข้อผิดพลาด
ห้องสมุดนี้อาจใช้งานได้โดยไม่ได้ตั้งใจ (หรือดูเหมือนจะใช้งานได้) ในรุ่นทับทิมอื่น ๆ อย่างไรก็ตามการสนับสนุนจะถูกจัดเตรียมไว้เฉพาะสำหรับรุ่นที่ระบุไว้ข้างต้นเท่านั้น
หากคุณต้องการให้ไลบรารีนี้สนับสนุนเวอร์ชันทับทิมอื่นหรือการใช้งานอื่น ๆ คุณอาจเป็นอาสาสมัครเป็นผู้ดูแล