NAME

Redis::Handle - A filehandle tie for a Redis queue

SYNOPSYS

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;

PRINT

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.