【发布时间】:2012-01-20 14:10:26
【问题描述】:
使用Attribute::Handlers实现重试逻辑可以吗
我有近 50 多个子例程,例如 verifyXXXX。我需要为所有这些子实现重试逻辑。我想在实际实现 sub 的地方编写这个重试逻辑。如果 sub 的返回值为 false/undef,那么它将再次重试。
subs 将以常规方式调用,因此调用者将不知道重试逻辑,例如。
verify_am_i_doing_good()
or die('sorry you are not doing as expected.');
verify_am_i_fine()
or die ('sorry you are not find.');
: :
这些函数的实际实现在包中是这样的。
use Attribute::Handlers;
use constant RETRY_LIMIT => 4;
use constant RETRY_DELAY => 2;
sub verify_am_i_doing_good : __retry
{
return 1 if ($x == $y);
return;
}
sub __retry : ATTR(CODE) {
my ($pkg, $sym, $code) = @_;
my $name = *{ $sym }{NAME};
no warnings 'redefine';
*{ $sym } = sub
{
my $self = $_[0];
my $result;
logMsg (INFO, "Executing subroutine $name with retry limit " . RETRY_LIMIT);
for (my $retryCount = 1; $retryCount <= RETRY_LIMIT; $retryCount++)
{
logMsg (INFO, "Executing subroutine $name with retry count $retryCount");
my $result = $code->( @_ );
if ($result)
{
logMsg (INFO, "Expected result observed in retry count $retryCount");
return wantarray ? @$result : $result;
}
else
{
logMsg (INFO, "Expected result is NOT observed in retry count $retryCount");
logMsg (INFO, "Retrying again by updating uixml");
sleep RETRY_DELAY;
$self->updateState();
}
}
logMsg (WARN, "Failed to verify expected result for subroutine $name with retry limit " . RETRY_LIMIT);
return;
};
}
使用 Attribute::Handlers 代替 Attribute::Attempts 的原因是,在失败的情况下,我需要在重试(重新执行)子例程之前调用另一个子例程 updateState()。
我从http://www.perl.com/pub/2007/04/12/lightning-four.html下面的帖子中得到了编写重试逻辑的想法
我主要担心的是,因为我使用这个 __retry 属性来处理近 50 多个潜艇。这样做是一个好习惯还是有什么简单的我可以做的?
我们将非常感谢您的帮助。
【问题讨论】:
标签: perl