Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
0be5d5d4
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0be5d5d4
编写于
8月 01, 2016
作者:
D
David Heinemeier Hansson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add exponentially_longer and custom wait algorithms
上级
08a92d47
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
68 addition
and
3 deletion
+68
-3
activejob/lib/active_job/exceptions.rb
activejob/lib/active_job/exceptions.rb
+25
-3
activejob/test/cases/exceptions_test.rb
activejob/test/cases/exceptions_test.rb
+39
-0
activejob/test/jobs/retry_job.rb
activejob/test/jobs/retry_job.rb
+4
-0
未找到文件。
activejob/lib/active_job/exceptions.rb
浏览文件 @
0be5d5d4
...
...
@@ -12,7 +12,10 @@ module ClassMethods
# holding queue for inspection.
#
# ==== Options
# * <tt>:wait</tt> - Re-enqueues the job with the specified delay in seconds (default: 3 seconds)
# * <tt>:wait</tt> - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds),
# as a computing proc that the number of executions so far as an argument, or as a symbol reference of
# <tt>:exponentially_longer<>, which applies the wait algorithm of <tt>(executions ** 4) + 2</tt>
# (first wait 3s, then 18s, then 83s, etc)
# * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts)
# * <tt>:queue</tt> - Re-enqueues the job on a different queue
# * <tt>:priority</tt> - Re-enqueues the job with a different priority
...
...
@@ -20,9 +23,14 @@ module ClassMethods
# ==== Examples
#
# class RemoteServiceJob < ActiveJob::Base
# retry_on Net::OpenTimeout, wait: 30.seconds, attempts: 10
# retry_on CustomAppException # defaults to 3s wait, 5 attempts
# retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
# retry_on ActiveRecord::StatementInvalid, wait: 5.seconds, attempts: 3
# retry_on Net::OpenTimeout, wait: :exponentially_longer, attempts: 10
#
# def perform(*args)
# # Might raise CustomAppException or AnotherCustomAppException for something domain specific
# # Might raise ActiveRecord::StatementInvalid when a local db deadlock is detected
# # Might raise Net::OpenTimeout when the remote service is down
# end
# end
...
...
@@ -30,7 +38,7 @@ def retry_on(exception, wait: 3.seconds, attempts: 5, queue: nil, priority: nil)
rescue_from
exception
do
|
error
|
if
executions
<
attempts
logger
.
error
"Retrying
#{
self
.
class
}
in
#{
wait
}
seconds, due to a
#{
exception
}
. The original exception was
#{
error
.
cause
.
inspect
}
."
retry_job
wait:
wait
,
queue:
queue
,
priority:
priority
retry_job
wait:
determine_delay
(
wait
)
,
queue:
queue
,
priority:
priority
else
logger
.
error
"Stopped retrying
#{
self
.
class
}
due to a
#{
exception
}
, which reoccurred on
#{
executions
}
attempts. The original exception was
#{
error
.
cause
.
inspect
}
."
raise
error
...
...
@@ -81,5 +89,19 @@ def discard_on(exception)
def
retry_job
(
options
=
{})
enqueue
options
end
private
def
determine_delay
(
seconds_or_algorithm
)
case
seconds_or_algorithm
when
:exponentially_longer
(
executions
**
4
)
+
2
when
Integer
seconds
=
seconds_or_algorithm
seconds
when
Proc
algorithm
=
seconds_or_algorithm
algorithm
.
call
(
executions
)
end
end
end
end
activejob/test/cases/exceptions_test.rb
浏览文件 @
0be5d5d4
require
'helper'
require
'jobs/retry_job'
require
'byebug'
class
ExceptionsTest
<
ActiveSupport
::
TestCase
setup
do
...
...
@@ -45,3 +46,41 @@ class ExceptionsTest < ActiveSupport::TestCase
assert_equal
"Raised DiscardableError for the 1st time"
,
JobBuffer
.
last_value
end
end
class
ExponentiallyBackoffExceptionsTest
<
ActiveJob
::
TestCase
setup
do
JobBuffer
.
clear
end
test
"exponentially retrying job"
do
travel_to
Time
.
now
perform_enqueued_jobs
do
assert_performed_with
at:
(
Time
.
now
+
3
.
seconds
).
to_i
do
assert_performed_with
at:
(
Time
.
now
+
18
.
seconds
).
to_i
do
assert_performed_with
at:
(
Time
.
now
+
83
.
seconds
).
to_i
do
assert_performed_with
at:
(
Time
.
now
+
258
.
seconds
).
to_i
do
RetryJob
.
perform_later
'ExponentialWaitTenAttemptsError'
,
5
end
end
end
end
end
end
test
"custom wait retrying job"
do
travel_to
Time
.
now
perform_enqueued_jobs
do
assert_performed_with
at:
(
Time
.
now
+
2
.
seconds
).
to_i
do
assert_performed_with
at:
(
Time
.
now
+
4
.
seconds
).
to_i
do
assert_performed_with
at:
(
Time
.
now
+
6
.
seconds
).
to_i
do
assert_performed_with
at:
(
Time
.
now
+
8
.
seconds
).
to_i
do
RetryJob
.
perform_later
'CustomWaitTenAttemptsError'
,
5
end
end
end
end
end
end
end
\ No newline at end of file
activejob/test/jobs/retry_job.rb
浏览文件 @
0be5d5d4
...
...
@@ -3,11 +3,15 @@
class
DefaultsError
<
StandardError
;
end
class
ShortWaitTenAttemptsError
<
StandardError
;
end
class
ExponentialWaitTenAttemptsError
<
StandardError
;
end
class
CustomWaitTenAttemptsError
<
StandardError
;
end
class
DiscardableError
<
StandardError
;
end
class
RetryJob
<
ActiveJob
::
Base
retry_on
DefaultsError
retry_on
ShortWaitTenAttemptsError
,
wait:
1
.
second
,
attempts:
10
retry_on
ExponentialWaitTenAttemptsError
,
wait: :exponentially_longer
,
attempts:
10
retry_on
CustomWaitTenAttemptsError
,
wait:
->
(
executions
)
{
executions
*
2
},
attempts:
10
discard_on
DiscardableError
def
perform
(
raising
,
attempts
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录