perl – 异常后重试操作:请批评我的代码
发布时间:2020-12-16 06:20:04 所属栏目:大数据 来源:网络整理
导读:我的Perl应用程序使用暂时不可用的资源,导致使用die的异常.最值得注意的是,它访问由多个线程共享的SQLite数据库以及通过DBIx :: Class使用的其他应用程序.每当发生此类异常时,都应重试该操作,直到达到超时. 我更喜欢简洁的代码,因此我很快就厌倦了 为每个这
我的Perl应用程序使用暂时不可用的资源,导致使用die的异常.最值得注意的是,它访问由多个线程共享的SQLite数据库以及通过DBIx :: Class使用的其他应用程序.每当发生此类异常时,都应重试该操作,直到达到超时.
我更喜欢简洁的代码,因此我很快就厌倦了 use Time::HiRes 'sleep'; use Carp; # [...] for (0..150) { sleep 0.1 if $_; eval { # database access }; next if $@ =~ /database is locked/; } croak $@ if $@; …所以我将它们放入(特定于DB访问)功能: sub _retry { my ( $timeout,$func ) = @_; for (0..$timeout*10) { sleep 0.1 if $_; eval { $func->(); }; next if $@ =~ /database is locked/; } croak $@ if $@; } 我称之为: my @thingies; _retry 15,sub { $schema->txn_do( sub { @thingies = $thingie_rs->search( { state => 0,job_id => $job->job_id },{ rows => $self->{batchsize} } ); if (@thingies) { for my $thingie (@thingies) { $thingie->update( { state => 1 } ); } } } ); }; 有没有更好的方法来实现这个?我是在重新发明轮子吗?是 解决方法
我可能倾向于写这样的重试:
sub _retry { my ( $retrys,$func ) = @_; attempt: { my $result; # if it works,return the result return $result if eval { $result = $func->(); 1 }; # nah,it failed,if failure reason is not a lock,croak croak $@ unless $@ =~ /database is locked/; # if we have 0 remaining retrys,stop trying. last attempt if $retrys < 1; # sleep for 0.1 seconds,and then try again. sleep 0.1; $retrys--; redo attempt; } croak "Attempts Exceeded $@"; } 它与现有代码的工作方式不同,但有一些优点. >我摆脱了* 10的东西,就像另一张海报,我无法辨别其目的. 更多建议(但稍微不那么理性)的抽象: sub do_update { my %params = @_; my @result; $params{schema}->txn_do( sub { @result = $params{rs}->search( @{ $params{search} } ); return unless (@result); for my $result_item (@result) { $result_item->update( @{ $params{update} } ); } } ); return @result; } my $data = _retry 15,sub { do_update( schema => $schema,rs => $thingy_rs,search => [ { state => 0,{ rows => $self->{batchsize} } ],update => [ { state => 1 } ],); }; 这些也可能是您代码的便利补充. (未经测试) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |