This queue is for tickets about the Cache-Memcached-Fast CPAN distribution.

Report information
The Basics
Id:
41077
Status:
resolved
Priority:
Low/Low

People
Owner:
Nobody in particular
Requestors:
norbi [...] nix.hu
Cc:
AdminCc:

BugTracker
Severity:
Wishlist
Broken in:
0.13
Fixed in:
(no value)

Attachments
Cache-Memcached-Fast-disconnect_all.diff



Subject: disconnect_all implementation
As the POD says, disconnect_all() is still to be implemented. Unfortunately, it is necessary to call it in a mod_perl environment. The Cache::Memcached::Managed wrapper module already tries to detect forking and calls it when appropriate, but the documented workaround (ie. undefining the object to trigger its destruction) cannot be used with Cache::Memcached::Managed (without overwriting its reset method, and that's better to avoid). Please check the attached patch for a preliminary implementation of disconnect_all. Please let me know what I should change.
Subject: Cache-Memcached-Fast-disconnect_all.diff
diff -Naur Cache-Memcached-Fast-0.13/Fast.xs Cache-Memcached-Fast-0.13-fixed/Fast.xs --- Cache-Memcached-Fast-0.13/Fast.xs 2008-10-13 17:41:49.000000000 +0200 +++ Cache-Memcached-Fast-0.13-fixed/Fast.xs 2008-11-20 00:35:18.000000000 +0100 @@ -1255,3 +1255,11 @@ } OUTPUT: RETVAL + + +void +disconnect_all(memd) + Cache_Memcached_Fast * memd + PROTOTYPE: $ + CODE: + client_reinit(memd->c); diff -Naur Cache-Memcached-Fast-0.13/lib/Cache/Memcached/Fast.pm Cache-Memcached-Fast-0.13-fixed/lib/Cache/Memcached/Fast.pm --- Cache-Memcached-Fast-0.13/lib/Cache/Memcached/Fast.pm 2008-10-13 17:41:49.000000000 +0200 +++ Cache-Memcached-Fast-0.13-fixed/lib/Cache/Memcached/Fast.pm 2008-11-20 00:35:18.000000000 +0100 @@ -1185,6 +1185,22 @@ # See Fast.xs. +=item C<disconnect_all> + + $memd->disconnect_all; + +Closes all open sockets to memcached servers. Must be called after +L<perlfunc/fork> if the parent process has open sockets to memcacheds (as the +child process inherits the socket and thus two processes end up using the same +socket which leads to protocol errors.) + +I<Return:> The C<$memd> object. + +=cut + +# See Fast.xs. + + 1; __END__ @@ -1285,17 +1301,6 @@ Not supported. Perhaps will appear in the future releases. -=item C<disconnect_all> - -Not supported. Easy to add. Meanwhile to disconnect from all servers -you may do - - undef $memd; - -or - - $memd = undef; - =back diff -Naur Cache-Memcached-Fast-0.13/src/client.c Cache-Memcached-Fast-0.13-fixed/src/client.c --- Cache-Memcached-Fast-0.13/src/client.c 2008-10-13 17:41:49.000000000 +0200 +++ Cache-Memcached-Fast-0.13-fixed/src/client.c 2008-11-20 00:36:35.000000000 +0100 @@ -181,6 +181,27 @@ } +static inline +int +command_state_reinit(struct command_state *state) +{ + if (state->fd != -1) + close(state->fd); + + state->fd = -1; + state->last_cmd_noreply = 0; + + array_clear(state->iov_buf); + + state->generation = 0; + state->nowait_count = 0; + + state->pos = state->end = state->eol = state->buf; + + return 0; +} + + struct server { char *host; @@ -240,6 +261,20 @@ } +static inline +int +server_reinit(struct server *s) +{ + s->failure_count = 0; + s->failure_expires = 0; + + if (command_state_reinit(&s->cmd_state) != 0) + return MEMCACHED_FAILURE; + + return MEMCACHED_SUCCESS; +} + + struct index_node { int index; @@ -412,6 +447,19 @@ } +inline +void +client_reinit(struct client *c) +{ + struct server *s; + + for (array_each(c->servers, struct server, s)) + server_reinit(s); + + array_clear(c->str_buf); +} + + int client_set_ketama_points(struct client *c, int ketama_points) { diff -Naur Cache-Memcached-Fast-0.13/src/client.h Cache-Memcached-Fast-0.13-fixed/src/client.h --- Cache-Memcached-Fast-0.13/src/client.h 2008-10-13 17:41:49.000000000 +0200 +++ Cache-Memcached-Fast-0.13-fixed/src/client.h 2008-11-20 00:35:18.000000000 +0100 @@ -96,6 +96,10 @@ void client_destroy(struct client *c); +extern +void +client_reinit(struct client *); + /* client_set_ketama_points() should be called before adding any server. */ diff -Naur Cache-Memcached-Fast-0.13/t/01-connect.t Cache-Memcached-Fast-0.13-fixed/t/01-connect.t --- Cache-Memcached-Fast-0.13/t/01-connect.t 2008-10-13 17:41:49.000000000 +0200 +++ Cache-Memcached-Fast-0.13-fixed/t/01-connect.t 2008-11-20 00:35:18.000000000 +0100 @@ -11,8 +11,12 @@ if ($Memd::memd) { diag("Connected to " . scalar @Memd::addr . " memcached servers, lowest version $Memd::version_str"); - plan tests => 1; + plan tests => 2; pass('connected'); + + my $server_versions = $Memd::memd->server_versions; + $Memd::memd->disconnect_all; + is_deeply($Memd::memd->server_versions, $server_versions, "server_versions still works after disconnect_all"); } else { plan skip_all => $Memd::error; }
Thanks for the patch. I'm not convinced with '$memd = undef' "workaround" myself ;). I'll incorporate your patch in a week or two when time permits, have no time to do a careful review right now. Thanks again!
The patch is applied to 0.14.


This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.