Mojo-Redis
view release on metacpan or search on metacpan
lib/Mojo/Redis.pm view on Meta::CPAN
package Mojo::Redis;
use Mojo::Base 'Mojo::EventEmitter';
use Mojo::URL;
use Mojo::Redis::Connection;
use Mojo::Redis::Cache;
use Mojo::Redis::Cursor;
use Mojo::Redis::Database;
use Mojo::Redis::PubSub;
use Scalar::Util 'blessed';
our $VERSION = '3.29';
$ENV{MOJO_REDIS_URL} ||= 'redis://localhost:6379';
has encoding => 'UTF-8';
has max_connections => 5;
has protocol_class => do {
my $class = $ENV{MOJO_REDIS_PROTOCOL};
$class ||= eval { require Protocol::Redis::XS; Protocol::Redis::XS->VERSION('0.06'); 'Protocol::Redis::XS' };
$class ||= 'Protocol::Redis::Faster';
eval "require $class; 1" or die $@;
$class;
};
has pubsub => sub {
my $self = shift;
my $pubsub = Mojo::Redis::PubSub->new(redis => $self);
Scalar::Util::weaken($pubsub->{redis});
return $pubsub;
};
has url => sub { Mojo::URL->new($ENV{MOJO_REDIS_URL}) };
sub cache { Mojo::Redis::Cache->new(redis => shift, @_) }
sub cursor { Mojo::Redis::Cursor->new(redis => shift, command => [@_ ? @_ : (scan => 0)]) }
sub db { Mojo::Redis::Database->new(redis => shift) }
sub new {
my $class = shift;
return $class->SUPER::new(@_) unless @_ % 2 and ref $_[0] ne 'HASH';
my $url = shift;
$url = Mojo::URL->new($url) unless blessed $url and $url->isa('Mojo::URL');
return $class->SUPER::new(url => $url, @_);
}
sub _connection {
my ($self, %args) = @_;
$args{ioloop} ||= Mojo::IOLoop->singleton;
my $conn = Mojo::Redis::Connection->new(
encoding => $self->encoding,
protocol => $self->protocol_class->new(api => 1),
url => $self->url->clone,
%args
);
Scalar::Util::weaken($self);
$conn->on(connect => sub { $self->emit(connection => $_[0]) });
$conn;
}
sub _blocking_connection {
my $self = shift->_fork_safety;
# Existing connection
my $conn = $self->{blocking_connection};
return $conn->encoding($self->encoding) if $conn and $conn->is_connected;
# New connection
return $self->{blocking_connection} = $self->_connection(ioloop => $conn ? $conn->ioloop : Mojo::IOLoop->new);
}
sub _dequeue {
my $self = shift->_fork_safety;
# Exsting connection
while (my $conn = shift @{$self->{queue} || []}) { return $conn->encoding($self->encoding) if $conn->is_connected }
# New connection
return $self->_connection;
}
sub _enqueue {
my ($self, $conn) = @_;
my $queue = $self->{queue} ||= [];
push @$queue, $conn if $conn->is_connected and $conn->url eq $self->url and $conn->ioloop eq Mojo::IOLoop->singleton;
shift @$queue while @$queue > $self->max_connections;
}
sub _fork_safety {
my $self = shift;
delete @$self{qw(blocking_connection pid queue)} unless ($self->{pid} //= $$) eq $$; # Fork-safety
$self;
}
1;
=encoding utf8
=head1 NAME
Mojo::Redis - Redis driver based on Mojo::IOLoop
=head1 SYNOPSIS
=head2 Blocking
use Mojo::Redis;
my $redis = Mojo::Redis->new;
$redis->db->set(foo => 42);
$redis->db->expire(foo => 600);
warn $redis->db->get('foo');
=head2 Promises
$redis->db->get_p("mykey")->then(sub {
print "mykey=$_[0]\n";
})->catch(sub {
warn "Could not fetch mykey: $_[0]";
})->wait;
=head2 Pipelining
Pipelining is built into the API by sending a lot of commands and then use
L<Mojo::Promise/all> to wait for all the responses.
Mojo::Promise->all(
$db->set_p($key, 10),
$db->incrby_p($key, 9),
$db->incr_p($key),
$db->get_p($key),
$db->incr_p($key),
$db->get_p($key),
)->then(sub {
@res = map {@$_} @_;
})->wait;
=head1 DESCRIPTION
L<Mojo::Redis> is a Redis driver that use the L<Mojo::IOLoop>, which makes it
integrate easily with the L<Mojolicious> framework.
It tries to mimic the same interface as L<Mojo::Pg>, L<Mojo::mysql> and
L<Mojo::SQLite>, but the methods for talking to the database vary.
This module is in no way compatible with the 1.xx version of C<Mojo::Redis>
and this version also tries to fix a lot of the confusing methods in
C<Mojo::Redis2> related to pubsub.
This module is currently EXPERIMENTAL, and bad design decisions will be fixed
without warning. Please report at
L<https://github.com/jhthorsen/mojo-redis/issues> if you find this module
useful, annoying or if you simply find bugs. Feedback can also be sent to
C<jhthorsen@cpan.org>.
=head1 EVENTS
=head2 connection
$cb = $redis->on(connection => sub { my ($redis, $connection) = @_; });
Emitted when L<Mojo::Redis::Connection> connects to the Redis.
=head1 ATTRIBUTES
=head2 encoding
$str = $redis->encoding;
$redis = $redis->encoding("UTF-8");
The value of this attribute will be passed on to
L<Mojo::Redis::Connection/encoding> when a new connection is created. This
means that updating this attribute will not change any connection that is
in use.
Default value is "UTF-8".
=head2 max_connections
$int = $redis->max_connections;
$redis = $redis->max_connections(5);
Maximum number of idle database handles to cache for future use, defaults to
5. (Default is subject to change)
=head2 protocol_class
$str = $redis->protocol_class;
$redis = $redis->protocol_class("Protocol::Redis::XS");
Default to L<Protocol::Redis::XS> if the optional module is available and at
least version 0.06, or falls back to L<Protocol::Redis::Faster>.
=head2 pubsub
$pubsub = $redis->pubsub;
Lazy builds an instance of L<Mojo::Redis::PubSub> for this object, instead of
returning a new instance like L</db> does.
=head2 url
$url = $redis->url;
$redis = $redis->url(Mojo::URL->new("redis://localhost/3"));
Holds an instance of L<Mojo::URL> that describes how to connect to the Redis server.
=head1 METHODS
=head2 db
$db = $redis->db;
Returns an instance of L<Mojo::Redis::Database>.
=head2 cache
$cache = $redis->cache(%attrs);
Returns an instance of L<Mojo::Redis::Cache>.
=head2 cursor
$cursor = $redis->cursor(@command);
Returns an instance of L<Mojo::Redis::Cursor> with
L<Mojo::Redis::Cursor/command> set to the arguments passed. See
L<Mojo::Redis::Cursor/new>. for possible commands.
=head2 new
$redis = Mojo::Redis->new("redis://localhost:6379/1");
$redis = Mojo::Redis->new(Mojo::URL->new->host("/tmp/redis.sock"));
$redis = Mojo::Redis->new(\%attrs);
$redis = Mojo::Redis->new(%attrs);
Object constructor. Can coerce a string into a L<Mojo::URL> and set L</url>
if present.
=head1 AUTHORS
Jan Henning Thorsen - C<jhthorsen@cpan.org>
Dan Book - C<grinnz@grinnz.com>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2018, Jan Henning Thorsen.
This program is free software, you can redistribute it and/or modify it under
the terms of the Artistic License version 2.0.
=cut
( run in 0.257 second using v1.01-cache-2.11-cpan-3989ada0592 )