Cache-Memcached-Managed

 view release on metacpan or  search on metacpan

lib/Cache/Memcached/Managed.pm  view on Meta::CPAN

            # regular array spec already
            elsif ( $type eq 'ARRAY' ) {
                push @all_servers, @{$spec};
            }

            # huh?
            else {
                undef $parameters;
            }
        }

        # huh?
        die "Don't know how to handle '$spec' as server specification"
          if !$parameters;

        # create the object for the backend
        $self{$_} = $memcached_class->new($parameters);
    }

    # huh?
    die "No valid data server specification found" if !blessed $self{data};

    # set directory server as data server if there was no data server
    $self{directory} = $self{data} if !blessed $self{directory};

    # remember the pid for fork checking
    $self{_last_pid} = $$;

    # set server specification
    $self{servers} = [ sort @all_servers ];

    return bless \%self,$class;
} #new

#---------------------------------------------------------------------------
#
# Instance methods
#
#---------------------------------------------------------------------------
# add
#
# Add ID + value, only done if not yet in the cache
#
#  IN: 1 instantiated object
#      2 value
#      3 id
# OUT: 1 true if successful
#
# or:
#
#  IN: 1 instantiated object
#      2..N parameter hash
# OUT: 1 true if successful

sub add { shift->_do( 'add',@_ ) } #add

#---------------------------------------------------------------------------
# dead
#
# Cycles through all of the available memcached servers and checks whether
# they are alive or not.  Returns all of the memcached servers that seem to
# be inactive.
#
#  IN: 1 instantiated object
#      2 timeout to apply (default: 10 seconds)
# OUT: 1..N memcached servers that did not reply (in time)
#
#  or:
#
# OUT: 1 hash ref with dead servers

sub dead {

# Obtain the class
# Obtain the timeout
# Create key to be used
# Create value to be used

    my $self = shift;
    my $timeout = shift || $pingtime;
    my $key = $self->_unique_key;
    my $value = time;

# Initialize list of problem servers
# For all of the servers to be checked (in alphabetical order)
#  Create new memcached server object for this server only
#  Obtain value from which
#   Makes sure alarm() will do a die()
#   Set the alarm
#   Set the value in the server
#   Attempt to get it back
#   Delete the key 
#   Return the value obtained

    my @dead;
    foreach ($self->servers) {
        my $server = $self->{memcached_class}->new( {servers => [$_]} );
        my $fetched = eval {
            local $SIG{ALRM} = sub { die "timed out\n" };
            alarm $timeout;
            $server->set( $key,$value );
            my $result = $server->get( $key );
            $server->delete( $key ) if $result;
            $result;
        } || 0;

#  Reset the alarm
#  Mark server as problem if value obtained not equal to value stored

        alarm 0;
        push @dead,$_ if $fetched != $value;
    }

# Return list of problem servers (sorted) or as a hash ref

    return wantarray ? @dead : {map {$_ => undef} @dead};
} #dead

#---------------------------------------------------------------------------
# decr
#

lib/Cache/Memcached/Managed.pm  view on Meta::CPAN

management of groups of values, for simplified key generation and expiration,
as well as version and namespace management and a few other goodies.

These are the main differences between this module and the L<Cache::Memcached>
module.

=head2 automatic key generation

The calling subroutine provides the key (by default).  Whenever the "get"
and "set" operations occur in the same subroutine, you don't need to think
up an identifying key that will have to be unique across the entire cache.

=head2 ID refinement

An ID can be added to the (automatically) generated key (none is by default),
allowing easy identification of similar data objects (e.g. the primary key of
a Class::DBI object).  If necessary, a unique ID can be created automatically
(useful when logging events).

=head2 version management

The caller's package provides an identifying version (by default), allowing
differently formatted data-structures caused by source code changes, to live
separately from each other in the cache.

=head2 namespace support

A namespace identifier allows different realms to co-exist in the same cache (the uid by default).  This e.g. allows a group of developers to all use the same cache without interfering with each other.

=head2 group management

A piece of cached data can be assigned to any number of groups.  Cached data
can be retrieved and removed by specifying the group to which the data
belongs.  This can be used to selectively remove cached data that has been
invalidated by a database change, or to obtain logged events of which the
identification is not known (but the group name is).

=head2 easy (default) expiration specification

A default expiration per Cache::Memcached::Managed object can be specified.
Expirations can be used by using mnemonics D, H, M, S, (e.g. '2D3H' would
be 2 days and 3 hours).

=head2 automatic fork() detection

Sockets are automatically reset in forked processes, no manual reset needed.
This allows the module to be used to access cached data during the server
start phase in a mod_perl environment.

=head2 magical increment

Counters are automagically created with L<incr> if they don't exist yet.

=head2 instant invalidation

Support for the new "flush_all" memcached action to invalidate all data in
a cache in one fell swoop.

=head2 dead memcached server detection

An easy way to check whether all related memcached servers are still alive.

=head2 starting/stopping memcached servers

Easy start / stop of indicated memcached servers, mainly intended for
development and testing environments.

=head2 extensive test-suite

An extensive test-suite is included (which is sadly lacking in the
Cache::Memcached distribution).

=head1 BASIC PREMISES

The basic premise is that each piece of information that is to be cached,
can be identified by a L<key>, an optional L<ID>, a L<version> and a
L<namespace>.

The L<key> determines the basic identification of the value to be cached.
The L<ID> specifies a refinement on the basic identification.  The L<version>
ensures that differently formatted values with the same key and ID do not
interfere with each other.  The L<namespace> ensures that different realms
of information (for instance, for different users) do not interfere with each
other.

=head2 key

The default for the key is the fully qualified subroutine name from which
the cached value is accessed.  For instance, if a cached value is to be
accessed from subroutine "bar" in the Foo package, then the key is "Foo::bar".
Explicit keys can be specified and may contain any characters except the
L<delimiter>.

A special case is applicable if the cache is being accessed from the lowest
level in a script.  In that case the default key will be created consisted
of the server name (as determined by C<uname -n>) and the absolute path of
the executing script.

=head2 ID

If no ID is specified for a piece of information, then just the L<key> will be
assumed.  The ID can be any string.  It can for instance be the primary key
of a Class::DBI object.  ID's can be specified as a scalar value, or as list
ref, or as a hash ref (for instance, for multi-keyed Class::DBI objects).

Some examples:

 my $value = $cache->get( $id );

 my $value = $cache->get( [$id,$checkin,$checkout] );

 my $value =
  $cache->get( {id => $id,checkin => $checkin,checkout => $checkout} );

If the ID should be something unique, and you're not interested in the ID
per se (for instance, if you're only interested in the
L<group|"group management"> to which the information will be linked), you
can specify the string C<:unique> to have a unique ID automatically
generated.

=head2 version management



( run in 0.674 second using v1.01-cache-2.11-cpan-df04353d9ac )