AnyEvent-Redis-Federated

 view release on metacpan or  search on metacpan

lib/AnyEvent/Redis/Federated.pm  view on Meta::CPAN

	$self->{request_serial}++;
	my $rid = $self->{request_serial};
	$self->{request_state}->{$rid} = 1; # open request; 0 is cancelled
	print "scheduling request $rid: $_[0]\n" if $self->{debug};

	if ($call eq 'multi' or $call eq 'exec') {
		@$args = (); # these don't really take args
	}

	$r->$call(@$args, sub {
		if (not $self->{request_state}->{$rid}) {
			print "call found request $rid cancelled\n" if $self->{debug};
			delete $self->{request_state}->{$rid};
			$self->markServerDown($server);
			$cb->(undef);
			return;
		}
		$self->{cv}->end;
		$self->markServerUp($server);
		$self->{last_used}->{$server} = time;
		print "callback completed for request $rid\n" if $self->{debug};
		delete $self->{request_state}->{$rid};
		$cb->(shift);
	});
	return $self;
}

=head1 NAME

AnyEvent::Redis::Federated - Full-featured Async Perl Redis client

=head1 SYNOPSIS

  use AnyEvent::Redis::Federated;

  my $r = AnyEvent::Redis::Federated->new(%opts);

  # batch up requests and explicity wait for completion
  $redis->set("foo$_", "bar$_") for 1..20;
  $redis->poll;

  # send a request with a callback
  $redis->get("foo1", sub {
    my $val = shift;
    print "cb got: $val\n"; # should print "cb got: 1"
  });
  $redis->poll;

=head1 DESCRIPTION

This is a wrapper around AnyEvent::Redis which adds timeouts,
connection retries, multi-machine cluster configuration (including
consistent hashing), node groups, and other magic bits.

=head2 HASHING AND SCALING

Keys are run through a consistent hashing algorithm to map them to
"nodes" which ultimately map to instances defined by back-end
host:port entries.  For example, the C<redis_1> node may map to the
host and port C<redis1.example.com:63791>, but that'll all be
transparent to the user.

However, there are features in Redis that are handy if you know a
given set of keys lives on a single insance (a wildcard fetch like
C<KEYS gmail*>, for example).  To facilitate that, you can specify a
"key group" that will be hashed insead of hashing the key.

For example:

  key group: gmail
  key      : foo@gmail.com

  key group: gmail
  key      : bar@gmail.com

Put another way, the key group defaults to the key for the named
operation, but if specified, is used instead as the input to the
consistent hashing function.

Using the same key group means that multiple keys end up on the same
Redis instance.  To do so, simply change any key in a call to an
arrayref where item 0 is the key group and item 1 is the key.

  $r->set(['gmail', 'foo@gmail.com'], 'spammer', $cb);
  $r->set(['gmail', 'bar@gmail.com'], 'spammer', $cb);

Anytime a key is an arrayref, AnyEvent::Redis::Federated will assume
you're using a key group.

=head2 PERSISTENT CONNECTIONS

By default, AnyEvent::Redis::Federated will use a new connection for
each command.  You can enable persistent connections by passing a
C<persistent> agrument (with a true value) in C<new()>.  You will
likely also want to set a C<idle_timeout> value as well.  The
idle_timeout defaults to 0 (which means no timeout).  But if set to a
posistive value, that's the number of seconds that a connection is
allowed to remain idle before it is re-established.  A number up to 60
seconds is probably reasonable.

=head2 SHARED CONNECTIONS

Because creating AnyEvent::Redis::Federated objects isn't cheap (due
mainly to initializing the consistent hashing ring), there is a
mechanism for sharing a connection object among modules without prior
knowledge of each other.  If you specify a C<tag> in the C<new()>
constructor and another module in the same process tries to create an
object with the same tag, it will get a reference to the one you
created.

For example, in your code:

  my $redis = AnyEvent::Redis::Federated->new(tag => 'rate-limiter');

Then in another module:

  my $r = AnyEvent::Redis::Federated->new(tag => 'rate-limiter');

Both C<$redis> and C<$r> will be references to the same object.

Since the first module to create an object with a given tag gets to



( run in 1.600 second using v1.01-cache-2.11-cpan-39bf76dae61 )