NAME
Redis::Handle - A filehandle tie for a Redis queue
SYNOPSIS
tie *REDIS, 'Redis::Handle';
print REDIS "Foo bar baz\n";
print while <REDIS>; # Prints "Foo bar baz\n"
print REDIS "Foo", "Bar";
my @baz = <REDIS>; # @baz is now ("Foo","Bar")
print REDIS "Foo", "Bar";
print <REDIS>; # Prints "Foo"
DESCRIPTION
Redis::Handle
implements a tie interface to a Redis queue so that you can treat said queue as a filehandle. Pushing to the front of the queue is the same as a print
, and popping off the end of the queue is like a readline
.
METHODS
TIEHANDLE
Ties the filehandle to the clientId in Redis.
Usage
tie *CLIENT, "Redis::Handle", $clientId;
tie *CLIENT, 'Redis::Handle', $clientId,
timeout => 100,
host => 'example.com',
port => 5800;
# pass an existing Redis connection
tie *CLIENT, 'Redis::Handle', $clientId, $redis;
Sends the message(s) to the client. Since we're using an AnyEvent connection, events are still processed while waiting on Redis to process the push, including asynchronously pushing _other_ messages.
Usage
print CLIENT nfreeze({ text => "foo", from => "bar" });
print CLIENT nfreeze({ text => "foo" }), nfreeze({ text => "bar" }), "System message";
READLINE
Reads the next message or flushes the message queue (depending on context). This is a "blocking" operation, but, because we're using AnyEvent::Redis, other events are still processed while we wait. Since Redis's BLPOP
operation blocks the whole connection, this spawns a separate AnyEvent::Redis connection to deal with the blocking operation.
Usage
my $message = <CLIENT>; # Reads only the next one
my @messages = <CLIENT>; # Flushes the message queue into @messages
Helper methods for READLINE
If you pass _flush
a nonzero number, it will read that many messages. An explicit "0" means "read nothing", while an undef
means "read everything".
EOF
Just like the regular eof
call. Returns 1 if the next read will be the end of the queue or if the queue isn't open.
Returns the length of the buffer.
poll_once
Returns the AnyEvent::Condvar
of the a blocking pop operation on a Redis queue. This is useful if, for example, you want to handle a BLPOP
as an asynchronous PSGI handler, since a standard READLINE
operation throws a "recursive blocking wait" exception (because you're waiting on a CondVar
that's waiting on a CondVar
). It takes a tied
variable, an optional count
of the maximum number of messages to return, and a callback as its arguments.
Usage
sub get {
my ($self,$clientId) = (+shift,+shift);
my $output = tie local *CLIENT, 'Redis::MessageQueue', "$clientId:out";
$output->poll_once(sub {
$self->write(+shift);
$self->finish;
});
}
CLOSE
Cleanup code so that we don't end up with a bunch of open filehandles.