Можно ли использовать Attribute::Handlers
для реализации логики повторов
У меня почти 50+ подпрограмм, как verifyXXXX
. Мне нужно реализовать логику повтора для всех этих подпрограмм. Я хочу написать эту логику повторных попыток, где на самом деле реализована подпрограмма. Если возвращаемое значение sub - false / undef, то оно повторится снова.
подпрограммы будут вызываться обычным способом, так что вызывающая сторона не будет знать о логике повторения, что-то вроде.
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+ подпрограмм. Это хорошая практика, или я могу сделать что-нибудь простое?
Ваша помощь будет высоко оценена.