Skip Menu |

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

Report information
The Basics
Id: 41077
Status: resolved
Priority: 0/
Queue: Cache-Memcached-Fast

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

Bug Information
Severity: Wishlist
Broken in: 0.13
Fixed in: (no value)



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.