我想做一些概念上非常简单的事情,等待最多30秒才能完成redid发布。一旦它通过,我想要返回,或者如果它没有通过,我想在三十秒后返回。
perl Redis模块几乎包含了我想要的所有内容,只是在收到消息后我无法立即返回。
我使用的示例代码如下所示:
#!/usr/bin/perl
use Redis;
my $redisSub = Redis->new;
my $msg = 0;
my @topics = ('mykey');
my $savecallback = sub {
my ($message, $topic, $subscribed_topic) = @_;
print "Message received : $message\n";
$msg = $message;
# I tried adding in the following line, but it complains
# that: Missing required callback in call to unsubscribe()
#$redisSub->unsubscribe ( @topics , $savecallback);
};
$redisSub->subscribe ( @topics , $savecallback);
my $redis = Redis->new;
print "old: " . $redis->get('mykey') . "\n";
print "Waiting for message to be sent\n";
$redisSub->wait_for_messages(30);
if ($msg) {
print "old: " . $redis->get('mykey') . "\n";
} else {
print "Timeout occurred\n";
}
问题是wait_for_messages(30)
调用等待30秒的空闲活动,所以如果消息出现,它立即打印出“收到消息”,但是等待另外30秒再返回控制权剧本。我可以将其更改为wait_for_messages(0)
,但随后会立即返回,我需要将其包含在睡眠循环中,这会在检测到调用之外的变化时引入潜在的延迟。
仅使用Redis模块可以实现吗?或者是否需要使用AnyEvent::Redis::PipeRedis模块来执行此操作?
答案 0 :(得分:1)
Ans:你提到的没有这样的延迟。要在消息到达时不再等待,请使用unsubscribe(),但我还没有测试过。
如何:你必须这样做:
while ('true' ) {
$redisSub->wait_for_messages(30);
}
为什么:上面等待消息30秒,之后再等30秒,依此类推。但是每当订阅事件发生时,立即调用回调子程序,但wait_for_messages从原始状态继续(独立于调用/事件发生/事件未发生)。如果订阅的消息即将到来, wait_for_messages(n)将不会在n秒内返回。所以它继续等待30秒。因此,如果匹配发布每29秒发生10次,则wait_for_messages将仅在290 + 30秒后返回,返回值为10.(然后由于while('true')它将再次返回等待。)
Note :1) Do/should not add sleep in the above code.
Note :2) If your aim is to stop processing after receiving first
message, you have to use $redisSub->unsubscribe(..)
inside the call-back-subroutine.
答案 1 :(得分:1)
最后这对于这个要求是有效的://我不想在事件发生后继续等待//
# inside call back sub:
my $savecallback = sub {
$event_occured = 1 ; # this is important
$redisSub->unsubscribe(@topics,$savecallback) ; # as well as this.
my ($message, $topic, $subscribed_topic) = @_;
...
};
# The above function will not work. Because $savecallback referred inside is undefined before it was assigned since RHS is still in compilation. So the correct one:
sub savecallback {
$event_occured = 1 ; # this is important
$redisSub->unsubscribe(@topics,\&savecallback) ; # as well as this.
my ($message, $topic, $subscribed_topic) = @_;
...
};
.....
$redisSub->subscribe(@topics,\&savecallback) ;
$event_occurred = 0;
while ( ! event_occurred ) {
$redisSub->wait_for_messages(1);
}
在调用call-back-subroutine之后,代码仍然等待1整秒,但我认为没关系。 没有unsubscribe(),如果事件在不到一秒的时间内持续发生,代码将永远不会返回。