EV-Memcached

 view release on metacpan or  search on metacpan

lib/EV/Memcached.pm  view on Meta::CPAN

This module treats all keys and values as byte strings. Encode UTF-8
strings before passing them in:

    use Encode;
    $mc->set(foo => encode_utf8($val), sub { ... });
    $mc->get('foo', sub {
        my $val = decode_utf8($_[0]);
    });

=head1 CALLBACK CONVENTIONS

Every command callback receives C<($result, $err)>. On success C<$err>
is C<undef>; on protocol error C<$err> holds a string like C<NOT_STORED>
or C<NOT_FOUND>. On a cache miss for C<get>/C<gat>, B<both> arguments
are C<undef> (a miss is not an error).

Callback exceptions are caught with C<G_EVAL> and reported via C<warn>
so a stray C<die> never unwinds the libev event loop. To abort on
errors, set a flag and break the loop; do not rely on C<die>
propagating out of a callback.

=head1 CONSTRUCTOR

=head2 new(%options)

Construct an instance. All options are optional; with none, the client
is unconfigured and you must call C<connect> / C<connect_unix> later.
Specifying C<host> (or C<path>) at construction time triggers an
immediate non-blocking connect. C<on_connect> is always delivered from
the event loop, never synchronously from the constructor, so installing
handlers right after C<new> is safe.

    my $mc = EV::Memcached->new(
        host     => '127.0.0.1',
        port     => 11211,
        on_error => sub { warn "@_" },
    );

=head3 Connection

=over

=item host => $str

=item port => $int (default 11211)

TCP host and port. Mutually exclusive with C<path>.

=item path => $str

Unix socket path. Mutually exclusive with C<host>.

=item loop => $ev_loop

EV loop to attach to. Default: C<EV::default_loop>.

=item priority => $num (-2 to +2)

EV watcher priority. Higher = serviced before other EV watchers.

=item keepalive => $seconds

TCP keepalive idle time. Set to 0 to disable. Ignored on Unix sockets.

=back

=head3 Timeouts and flow control

=over

=item connect_timeout => $ms

Abort an in-progress non-blocking connect after this many milliseconds.
0 = no timeout (default). Applies to any connect that does not complete
immediately (including unix sockets under rare kernel backlog
conditions); immediately-completing connects finish on the next event
loop iteration without arming this timer.

=item command_timeout => $ms

Disconnect with C<"command timeout"> error if no response arrives
within this interval. The timer resets on every response from the
server. 0 = no timeout (default).

=item max_pending => $num

Cap on concurrent in-flight commands. Excess commands are held in a
local waiting queue. 0 = unlimited (default).

=item waiting_timeout => $ms

Maximum time a command may sit in the waiting queue before its callback
fires with C<"waiting timeout">. 0 = unlimited (default).

=item resume_waiting_on_reconnect => $bool

If true, the waiting queue survives a disconnect and is replayed on
reconnect. Default: false.

=back

=head3 Reconnect

=over

=item reconnect => $bool

Enable automatic reconnection on transport errors.

=item reconnect_delay => $ms (default 1000)

Delay before each reconnect attempt. The delay is always honored via a
timer; setting it to 0 still defers through the event loop (no
synchronous retry recursion).

=item max_reconnect_attempts => $num

Give up after this many consecutive failures and emit
C<"max reconnect attempts reached">. 0 = unlimited (default).

=back

=head3 Authentication

lib/EV/Memcached.pm  view on Meta::CPAN


Invalidate every item. Optional delay in seconds before the flush takes
effect. Without C<$cb>, sent as fire-and-forget (FLUSHQ).

=head2 noop([$cb])

No-operation round-trip. Useful as a pipeline fence to wait until all
previously-sent commands have been processed.

=head2 version([$cb->($version, $err)])

Server version string.

=head2 stats([$name,] [$cb->(\%stats, $err)])

Server statistics. Without C<$name>, returns the default stats group.
Common groups: C<settings>, C<items>, C<sizes>, C<slabs>, C<conns>.

=head1 AUTHENTICATION

=head2 sasl_auth($username, $password, [$cb])

Authenticate via SASL PLAIN. Auto-invoked on connect when both
C<username> and C<password> were passed to the constructor; call
manually only when authenticating after a no-auth construction.

=head2 sasl_list_mechs([$cb->($mechs, $err)])

Query the server's supported mechanisms; returns a space-separated
string such as C<"PLAIN">.

=head1 LOCAL CONTROL

=head2 skip_pending

Drain the in-flight queue, firing every callback with
C<(undef, "skipped")>. Responses for skipped commands are consumed and
discarded when they later arrive (strict FIFO opaque matching is
preserved); the connection genuinely stays usable for new commands.

=head2 skip_waiting

Same, but for the local waiting queue (commands not yet sent).

=head2 pending_count

Number of commands sent and awaiting a response.

=head2 waiting_count

Number of commands held in the local waiting queue (because the
connection is not ready, SASL is in progress, or C<max_pending> is
saturated).

=head1 ACCESSORS

The following options have a getter/setter of the same name (there are
no accessors for C<host>, C<port>, C<path>, C<username>, C<password>,
C<reconnect_delay>, C<max_reconnect_attempts>, or C<loop>). Calling
without arguments reads the current value; with one argument it writes
and (where meaningful, e.g. C<keepalive>) takes effect immediately.

=over

=item C<connect_timeout([$ms])>

=item C<command_timeout([$ms])>

=item C<max_pending([$num])>

=item C<waiting_timeout([$ms])>

=item C<resume_waiting_on_reconnect([$bool])>

=item C<priority([$num])>

=item C<keepalive([$seconds])>

=item C<reconnect_enabled>

Read-only; configure via C<reconnect>.

=item C<reconnect($enable, [$delay_ms], [$max_attempts])>

Reconfigure auto-reconnect at runtime.

=item C<on_error([$cb])>

=item C<on_connect([$cb])>

=item C<on_disconnect([$cb])>

Get/set the corresponding handler. Pass C<undef> to clear.

=back

=head1 DESTRUCTION

If C<$mc> goes out of scope while commands are in flight or queued,
every pending and waiting callback fires once with
C<(undef, "disconnected")>. This holds whether you call C<disconnect>
first or simply drop the reference -- including dropping the B<last>
reference from inside one of the object's own callbacks (deferred
DESTROY fires the remaining callbacks before tearing down).

The one exception is global destruction (interpreter shutdown): no
Perl callbacks are invoked then; queues are freed silently.

The clean shutdown idiom is:

    $mc->disconnect;   # drains queues, fires on_disconnect
    undef $mc;

If a callback closes over C<$mc> (a common mistake -- every reference
inside a callback closure keeps the object alive), break the cycle
before dropping the outer reference:

    $mc->on_error(undef);
    $mc->on_connect(undef);
    $mc->on_disconnect(undef);
    undef $mc;

DESTROY is reentrant-safe: if a callback fired during teardown drops
the last external reference to a separate C<EV::Memcached>, that
object's DESTROY is correctly deferred and run once unwound.

=head1 BINARY PROTOCOL NOTES

The wire format is the memcached binary protocol -- a 24-byte header
plus body, with each request tagged by an opaque field used for
in-flight matching and pipelining. Multi-get is sent as a run of
GETKQ packets ending in a NOOP fence: the server emits a response
only on hit, and the NOOP reply terminates the batch. Fire-and-forget
C<set>/C<flush> use the quiet SETQ / FLUSHQ opcodes so the server
sends no response at all.

Commands that can legitimately fail (C<add>, C<replace>, C<append>,
C<prepend>, C<delete>, C<incr>, ...) always use the non-quiet opcode so
error responses are consumed by the client even when the user passed no
callback. Response matching is strict FIFO per connection: responses
must arrive in request order, so only in-order servers are supported
(reordering proxies are unsupported). Keys are
validated against the 250-byte protocol limit before any bytes go on
the wire.

=head1 BENCHMARKS

Numbers from C<bench/benchmark.pl> on Linux, TCP loopback, 100-byte
values, Perl 5.40, memcached 1.6.41:

                         50K cmds    200K cmds
    Pipeline SET           213K        68K ops/sec
    Pipeline GET           216K        67K ops/sec
    Mixed workload         226K        69K ops/sec
    Fire-and-forget SET    1.13M      1.29M ops/sec  (SETQ)
    Multi-get (GETKQ)      1.30M      1.17M ops/sec  (per key)
    Sequential round-trip   41K        38K ops/sec

Fire-and-forget is roughly 5x faster than callback mode because there
is no per-command Perl SV allocation. Multi-get is the fastest read
path since misses generate no traffic. Callback-mode throughput drops
as batch size grows because SV allocation for closures dominates;
realistic workloads (interleaved sends and receives) stay close to the
50K-command column.

C<max_pending> overhead (200K commands):

    unlimited        ~131K ops/sec
    max_pending=500  ~126K ops/sec
    max_pending=100  ~120K ops/sec
    max_pending=50   ~117K ops/sec

Override C<BENCH_COMMANDS>, C<BENCH_VALUE_SIZE>, C<BENCH_HOST>, and
C<BENCH_PORT> to retune.



( run in 1.369 second using v1.01-cache-2.11-cpan-14f38c9f855 )