NAME

RedisDB - Module to access redis database

SYNOPSIS

use RedisDB;

my $redis = RedisDB->new(host => 'localhost', port => 6379);
$redis->set($key, $value);
my $value = $redis->get($key);

DESCRIPTION

This is alfa version, use on your own risk, interface is subject to change

This module provides interface to access redis database. It transparently handles disconnects and forks. It supports pipelining mode.

METHODS

$class->new(%options)

Creates new RedisDB object. The following options are allowed:

host

domain name of the host running redis server. Default: "localhost"

port

port to connect. Default: 6379

lazy

by default new establishes connection to the server. If this parameter is set, then connection will be established when you will send command to the server.

$self->execute($command, @arguments)

send command to the server and return server reply. It throws exception if server returns error. It may be more convenient to use instead of this method wrapper named after the redis command. E.g.:

$redis->execute('set', key => 'value');
# is the same as
$redis->set(key => 'value');

See "SUPPORTED REDIS COMMANDS" section for the full list of defined aliases.

Note, that you can't use execute if you have sent some commands in pipelining mode and haven't yet got all replies.

$self->send_command($command, @arguments)

send command to the server. Returns true if command was successfully sent, or dies if error occured. Note, that it doesn't return server reply, you should retrieve reply using get_reply method.

$self->reply_ready

This method may be used in pipelining mode to check if there are some replies already received from server. Returns number of replies available for reading.

$self->get_reply

receive reply from the server. Method croaks if server returns error reply.

SUPPORTED REDIS COMMANDS

Usually, instead of using execute method, you can just use methods with names matching names of the redis commands. The following methods are defined as wrappers around execute: append, auth, bgrewriteaof, bgsave, blpop, brpoplpush, config_get, config_set, config_resetstat, dbsize, debug_object, debug_segfault, decr, decrby, del, echo, exists, expire, expireat, flushall, flushdb, get, getbit, getrange, getset, hdel, hexists, hget, hgetall, hincrby, hkeys, hlen, hmget, hmset, hset, hsetnx, hvals, incr, incrby, info, keys, lastsave, lindex, linsert, llen, lpop, lpush, lpushx, lrange, lrem, lset, ltrim, mget, move, mset, msetnx, persist, ping, publish, quit, randomkey, rename, renamenx, rpop, rpoplpush, rpush, rpushx, sadd, save, scard, sdiff, sdiffstore, select, set, setbit, setex, setnx, setrange, shutdown, sinter, sinterstore, sismember, slaveof, smembers, smove, sort, spop, srandmember, srem, strlen, sunion, sunionstore, sync, ttl, type, zadd, zcard, zcount, zincrby, zinterstore, zrange, zrangebyscore, zrank, zremrangebyrank, zremrangebyscore, zrevrange, zrevrangebyscore, zrevrank, zscore, zunionstore

See description of all commands in redis documentation at http://redis.io/commands.

HANDLING OF SERVER DISCONNECTS

Redis server may close connection if it was idle for some time, also connection may be closed in case redis-server was restarted. RedisDB restores connection to the server but only if no data was lost as result of disconnect. E.g. if client was idle for some time and redis server closed connection, it will be transparently restored on sending next command. If you send a command and server closed connection without sending complete reply, connection will not be restored and module will throw exception.

PIPELINING SUPPORT

You can send commands in pipelining mode. In this case you sending multiple commands to the server without waiting for replies. You can use send_command method to send multiple commands to the server. reply_ready method may be used to check if some replies are already received. And get_reply method may be used to fetch received reply. Note, that you can't use execute method (or wrappers around it, like get or set) while in pipeline mode, you must receive replies on all pipelined commands first.

SUBSCRIPTIONS SUPPORT

RedisDB supports subscriptions to redis channels. In subscription mode you can subscribe to some channels and receive all messages sent to these channels. Every time RedisDB receives message for the channel it invokes callback provided by user. User can specify different callbacks for different channels. When in subscription mode you can subscribe to additional channels, or unsubscribe from channels you subscribed to, but you can't use any other redis commands like set, get, etc. Here's example of running in subscription mode:

my $message_cb = sub {
    my ($redis, $channel, $pattern, $message) = @_;
    print "$channel: $message\n";
};

my $control_cb = sub {
    my ($redis, $channel, $pattern, $message) = @_;
    if ($channel eq 'control.quit') {
        $redis->unsubscribe;
        $redis->punsubscribe;
    }
    elsif ($channel eq 'control.subscribe') {
        $redis->subscribe($message);
    }
};

subscription_loop(
    subscribe => [ 'news',  ],
    psubscribe => [ 'control.*' => $control_cb ],
    default_callback => $message_cb,
);

subscription_loop will subscribe you to news channel and control.* channels. It will call specified callbacks every time new message received. You can subscribe to additional channels sending their names to control.subscribe channel. You can unsubscribe from all channels by sending message to control.quit channel. Every callback receives four arguments: RedisDB object, channel for which message was received, pattern if you subscribed to this channel using psubscribe method, and message itself.

You can publish messages into channels using publish method. This method should be called when you in normal mode, and can't be used while you're in subscription mode.

Following methods can be used in subscribtion mode:

$self->subscription_loop(%parameters)

Enter into subscription mode. Function subscribes you to specified channels, waits for messages, and invokes callbacks for every received message. Function returns after you unsubscribed from all channels. It accepts following parameters:

default_callback

reference to the default callback. This callback is invoked for the message if you didn't specify other callback for the channel this message comes from.

subscribe

array reference. Contains list of channels you want to subscribe. Channel name may be optionally followed by reference to callback function for this channel. E.g.:

[ 'news', 'messages', 'errors' => \&error_cb, 'other' ]

channels "news", "messages", and "other" will use default callback, but for "errors" channel error_cb function will be used.

psubscribe

same as subscribe, but you specify patterns for channels' names.

All parameters are optional, but you must subscribe at least to one channel. Also if default_callback is not specified, you have to explicitely specify callback for every channel you're going to subscribe.

$self->subscribe($channel[, $callback])

Subscribe to additional $channel. If $callback is not specified, default callback will be used.

$self->psubscribe($pattern[, $callback])

Subscribe to additional channels matching $pattern. If $callback is not specified, default callback will be used.

$self->unsubscribe([@channels])

Unsubscribe from the listed @channels. If no channels specified, unsubscribe from all channels.

$self->punsubscribe([@patterns])

Unsubscribe from the listed @patterns. If no patterns specified, unsubscribe from all channels to which you subscribed using psubscribe.

$self->subscribed

Return list of channels to which you have subscribed using subscribe

$self->psubscribed

Return list of channels to which you have subscribed using psubscribe

SEE ALSO

Redis, Redis::hiredis, AnyEvent::Redis

WHY ANOTHER ONE

I was in need of a client for redis database. AnyEvent::Redis didn't suite me as it requires event loop, and it didn't fit into existing code. Problem with Redis is that it doesn't (at the time I write this) reconnect to the server if connection was closed after timeout or as result or server restart, and it doesn't support pipelining. After analizing what I need to change in Redis in order to get all I want (see TODO), I decided that it will be simplier to write new module from scratch. This also solves the problem of backward compatibility. Pedro Melo, maintainer of Redis have plans to implement some of these features too.

TODO

  • Test all commands

  • Handle cases when client is not interested in replies

  • Transactions support (MULTI, EXEC, DISCARD, WATCH, UNWATCH)

  • Subscriptions support (PSUBSCRIBE, PUNSUBSCRIBE, SUBSCRIBE, UNSUBSCRIBE)

BUGS

Please report any bugs or feature requests to bug-redisdb at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=RedisDB. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

AUTHOR

Pavel Shaydo, <zwon at cpan.org>

LICENSE AND COPYRIGHT

Copyright 2011 Pavel Shaydo.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.