使用Redis和Perl,如何等待一个已发布的方法

时间:2016-02-09 23:38:52

标签: perl redis

我想做一些概念上非常简单的事情,等待最多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模块来执行此操作?

2 个答案:

答案 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(),如果事件在不到一秒的时间内持续发生,代码将永远不会返回。