File Coverage

blib/lib/RedisDB/Sentinel.pm
Criterion Covered Total %
statement 15 34 44.1
branch 0 6 0.0
condition n/a
subroutine 5 9 55.5
pod 1 1 100.0
total 21 50 42.0


line stmt bran cond sub pod time code
1             package RedisDB::Sentinel;
2              
3 1     1   862 use strict;
  1         3  
  1         25  
4 1     1   4 use warnings;
  1         1  
  1         39  
5             our $VERSION = "2.55";
6             $VERSION = eval $VERSION;
7              
8 1     1   4 use Carp;
  1         1  
  1         44  
9 1     1   4 use RedisDB;
  1         2  
  1         15  
10 1     1   3 use Try::Tiny;
  1         1  
  1         312  
11              
12             =head1 NAME
13              
14             RedisDB::Sentinel - interface to redis servers managed by sentinel
15              
16             =head1 SYNOPSIS
17              
18             use RedisDB::Sentinel;
19              
20             my $redis = RedisDB::Sentinel->connect_to_master(
21             service => $service_name,
22             sentinels => [
23             {
24             host => 'host1',
25             port => 26379
26             },
27             {
28             host => 'host2',
29             port => 26379
30             },
31             ],
32             );
33             $redis->set( $key, $value );
34             my $value = $redis->get($key);
35              
36             =head1 DESCRIPTION
37              
38             This module provides interface to access redis servers managed by sentinels, it
39             handles communication with sentinels and dispatches commands to the master
40             redis.
41              
42             =head1 METHODS
43              
44             =cut
45              
46             =head2 $class->connect_to_master(%params)
47              
48             retrieve information about master from sentinel and return RedisDB object
49             connected to master. Additionally sets on_conect_error handler to retrieve
50             information about new master in case of reconnect. Requires two parameters:
51              
52             =over 4
53              
54             =item B
55              
56             service name to which you want to connect
57              
58             =item B
59              
60             list of sentinels. Each element is a hash with "host" and "port" elements.
61              
62             =back
63              
64             Other parameters are passed as is to constructor of RedisDB object. Note, that
65             host, port, and on_connect_error parameters will be overwritten by
66             RedisDB::Sentinel
67              
68             =cut
69              
70             sub connect_to_master {
71 0     0 1   my ( $class, %args ) = @_;
72              
73             my $service = delete $args{service}
74 0 0         or croak '"service" parameter is required';
75 0 0         my @sentinels = @{ delete $args{sentinels} }
  0            
76             or croak '"sentinels" parameter is required';
77              
78 0           my ( $host, $port ) = _get_master_from_sentinel( $service, \@sentinels );
79             return RedisDB->new(
80             %args,
81             host => $host,
82             port => $port,
83             on_connect_error => sub {
84 0     0     my ( $redis, $error ) = @_;
85 0           my ( $host, $port ) = _get_master_from_sentinel( $service, \@sentinels );
86 0           $redis->{host} = $host;
87 0           $redis->{port} = $port;
88 0           return;
89             },
90 0           );
91             }
92              
93             sub _get_master_from_sentinel {
94 0     0     my ( $service, $sentinels ) = @_;
95              
96 0           for ( 1 .. @$sentinels ) {
97             my $master = try {
98 0     0     my $sentinel = RedisDB->new( %{ $sentinels->[0] } );
  0            
99 0           $sentinel->execute( 'sentinel', 'get-master-addr-by-name', $service );
100 0           };
101 0 0         return @$master if $master;
102 0           push @$sentinels, shift @$sentinels;
103             }
104             }
105              
106             1;
107              
108             __END__