.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Cache::Memcached::Managed 3pm" .TH Cache::Memcached::Managed 3pm "2019-11-20" "perl v5.30.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Cache::Memcached::Managed \- provide API for managing cached information .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Cache::Memcached::Managed; \& \& my $cache = Cache::Memcached::Managed\->new( \*(Aq127.0.0.1:12345\*(Aq ); \& \& $cache\->set( $value ); \& \& $cache\->set( $value,$id ); \& \& $cache\->set( value => $value, \& id => $id, \& key => $key, \& version => "1.1", \& namespace => \*(Aqfoo\*(Aq, \& expiration => \*(Aq1D\*(Aq, ); \& \& my $value = $cache\->get( $id ); \& \& my $value = $cache\->get( id => $id, \& key => $key ); .Ve .SH "VERSION" .IX Header "VERSION" This documentation describes version 0.22. .SH "DIFFERENCES FROM THE Cache::Memcached API" .IX Header "DIFFERENCES FROM THE Cache::Memcached API" The Cache::Memcached::Managed module provides an \s-1API\s0 to values, cached in one or more memcached servers. Apart from being very similar to the \s-1API\s0 of Cache::Memcached, the Cached::Memcached::Managed \s-1API\s0 allows for management of groups of values, for simplified key generation and expiration, as well as version and namespace management and a few other goodies. .PP These are the main differences between this module and the Cache::Memcached module. .SS "automatic key generation" .IX Subsection "automatic key generation" The calling subroutine provides the key (by default). Whenever the \*(L"get\*(R" and \*(L"set\*(R" 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. .SS "\s-1ID\s0 refinement" .IX Subsection "ID refinement" An \s-1ID\s0 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 \s-1ID\s0 can be created automatically (useful when logging events). .SS "version management" .IX Subsection "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. .SS "namespace support" .IX Subsection "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. .SS "group management" .IX Subsection "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). .SS "easy (default) expiration specification" .IX Subsection "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). .SS "automatic \fBfork()\fP detection" .IX Subsection "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. .SS "magical increment" .IX Subsection "magical increment" Counters are automagically created with incr if they don't exist yet. .SS "instant invalidation" .IX Subsection "instant invalidation" Support for the new \*(L"flush_all\*(R" memcached action to invalidate all data in a cache in one fell swoop. .SS "dead memcached server detection" .IX Subsection "dead memcached server detection" An easy way to check whether all related memcached servers are still alive. .SS "starting/stopping memcached servers" .IX Subsection "starting/stopping memcached servers" Easy start / stop of indicated memcached servers, mainly intended for development and testing environments. .SS "extensive test-suite" .IX Subsection "extensive test-suite" An extensive test-suite is included (which is sadly lacking in the Cache::Memcached distribution). .SH "BASIC PREMISES" .IX Header "BASIC PREMISES" The basic premise is that each piece of information that is to be cached, can be identified by a key, an optional \s-1ID\s0, a version and a namespace. .PP The key determines the basic identification of the value to be cached. The \s-1ID\s0 specifies a refinement on the basic identification. The version ensures that differently formatted values with the same key and \s-1ID\s0 do not interfere with each other. The namespace ensures that different realms of information (for instance, for different users) do not interfere with each other. .SS "key" .IX Subsection "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 \*(L"bar\*(R" in the Foo package, then the key is \*(L"Foo::bar\*(R". Explicit keys can be specified and may contain any characters except the delimiter. .PP 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 \f(CW\*(C`uname \-n\*(C'\fR) and the absolute path of the executing script. .SS "\s-1ID\s0" .IX Subsection "ID" If no \s-1ID\s0 is specified for a piece of information, then just the key will be assumed. The \s-1ID\s0 can be any string. It can for instance be the primary key of a Class::DBI object. \s-1ID\s0'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). .PP Some examples: .PP .Vb 1 \& my $value = $cache\->get( $id ); \& \& my $value = $cache\->get( [$id,$checkin,$checkout] ); \& \& my $value = \& $cache\->get( {id => $id,checkin => $checkin,checkout => $checkout} ); .Ve .PP If the \s-1ID\s0 should be something unique, and you're not interested in the \s-1ID\s0 per se (for instance, if you're only interested in the group to which the information will be linked), you can specify the string \f(CW\*(C`:unique\*(C'\fR to have a unique \s-1ID\s0 automatically generated. .SS "version management" .IX Subsection "version management" The version indicates which version (generation) of the data is to be fetched or stored. By default, it takes the value of the \f(CW$VERSION\fR variable of the package to which the key is associated. This allows new modules that cache information to be easily installed in a server park without having to fear data format changes. .PP A specific version can be specified with each of the add, decr, get, get_multi, incr, replace and set to indicate the link with the group of the information being cached. .PP .Vb 3 \& Please always use a string as the version indicator. Using floating point \& values may yield unexpected results, where B<1.0> would actually use B<1> \& as the version. .Ve .SS "namespace management" .IX Subsection "namespace management" The namespace indicates the realm to which the data belongs. By default, the effective user id of the process (as known by $>) is assumed. This allows several users to share the same \*(L"data server\*(R" and \&\*(L"directory server\*(R", while each still having their own set of cached data. .PP A specific namespace can be specified with each of the add, decr, get, get_multi, incr, replace and set to indicate the link with the group of the information being cached. .SS "data server" .IX Subsection "data server" The data server is a Cache::Memcached (compatible) object in which all data (keyed to a \*(L"data key\*(R") is stored. It uses one or more memcached servers. The data server can be obtained with the data object. .SS "data key" .IX Subsection "data key" The data key identifies a piece of data in the \*(L"data server\*(R". It is formed by appending the namespace (by default the user id of the process), version, key and \s-1ID\s0, separated by the delimiter. .PP If a scalar value is specified as an \s-1ID,\s0 then that value is used. .PP If the \s-1ID\s0 is specified as a list ref, then the values are concatenated with the delimiter. .PP If the \s-1ID\s0 is specified as a hash ref, then the sorted key and value pairs are concatenated with the delimiter. .SS "group management" .IX Subsection "group management" The group concept was added to allow easier management of cached information. Since it is impossible to delete cached information from the \*(L"data server\*(R" by a matching a wildcard key value (because you can only access cached information if you know the exact key), another way was needed to access groups of cached data. .PP Another way that would not need another (database) backend or be dependent on running on a single hardware. This is achieved by using a \&\*(L"directory server\*(R", which is basically just another memcached server dedicated to keeping a directory of data kept in the \*(L"data server\*(R". .PP The group concept allows you to associate a given \*(L"data key\*(R" to a named group and an group \s-1ID\s0 value (e.g. the group named \*(L"group\*(R" and the name of an \&\s-1SQL\s0 table). This information is then stored in the \*(L"directory server\*(R", from which it is possible to obtain a list of \*(L"data keys\*(R" associated with the group name and the \s-1ID\s0 value. .PP In the current implementation, the only one group name is recognized by default: .IP "group" 2 .IX Item "group" Intended for generic data without specific keys. .PP You can specify your own set of group names with the \*(L"group_names\*(R" parameter in new. .PP Group names and \s-1ID\s0's can be specified with each of the add, decr, incr, replace and set to indicate the link with the group of the information being cached. .PP The pseudo group \s-1ID\s0 '\f(CW\*(C`:key\*(C'\fR' can be specified to indicate that the key should be used for the group \s-1ID.\s0 This is usually used in conjunction with the generic '\f(CW\*(C`group\*(C'\fR' group name .PP A list of valid group names can be obtained with the group_names method. .SS "directory server" .IX Subsection "directory server" The directory server is a Cache::Memcached (compatible) object that is being used to store \*(L"data key\*(R"s (as opposed to the data itself) used in \&\*(L"group management\*(R". If no directory server was specified, then the data server will be assumed. .PP If there are multiple memcached servers used for the \*(L"data server\*(R", then it is advised to use a separate directory server (as a failure in one of the memcached backend servers will leave you with an incomplete directory otherwise). .PP Should the directory server fail, and it is vital that there is no stale data in the data server, then a flush_all would need to be executed to ensure that no stale data remains behind. Of course, this will also delete all non-stale data from the data server, so your mileage may vary. .SS "expiration specification" .IX Subsection "expiration specification" Expiration can be specified in seconds, but, for convenience, can also be specified in days, hours and minutes (and seconds). This is indicated by a number, immediately followed by a letter \fBD\fR (for days) or \fBH\fR (for hours) or \fBM\fR (for minutes) or \fBS\fR (for seconds). For example: .PP .Vb 1 \& 2D3H .Ve .PP means 2 days and 3 hours, which means \fB183600\fR seconds. .SS "transparent fork handling" .IX Subsection "transparent fork handling" Using this module, you do not have to worry if everything will still work after a \fBfork()\fR. As soon as it is detected that the process has forked, new handles will be opened to the memcached servers in the child process (so the meticulous calling of \*(L"disconnect_all\*(R" of Cache::Memcached is no longer needed). .PP Transparent thread handling is still on the todo list. .SH "CLASS METHODS" .IX Header "CLASS METHODS" .SS "new" .IX Subsection "new" .Vb 1 \& my $cache = Cache::Memcached::Managed\->new; \& \& my $cache = Cache::Memcached::Managed\->new( \*(Aq127.0.0.1:11311\*(Aq ); \& \& my $cache = Cache::Memcached::Managed\->new( \& data => \*(Aq127.0.0.1:11311\*(Aq, # default: \*(Aq127.0.0.1:11211\*(Aq \& directory => \*(Aq127.0.0.1:11411\*(Aq, # default: data \& delimiter => \*(Aq;\*(Aq, # default: \*(Aq#\*(Aq \& expiration => \*(Aq1H\*(Aq, # default: \*(Aq1D\*(Aq \& flush_interval => 10, # default: none \& namespace => \*(Aqfoo\*(Aq, # default: $> ($EUID) \& group_names => [qw(foo bar)], # default: [\*(Aqgroup\*(Aq] \& \& memcached_class => \*(AqCached::Memcached::Fast\*(Aq, # default: \*(AqCache::Memcached\*(Aq \& ); \& \& my $cache = Cache::Memcached::Managed\->new( inactive => 1 ); .Ve .PP Create a new Cache::Memcached::Managed object. If there are less than two input parameters, then the input parameter is assumed to be the value of the \*(L"data\*(R" field, with a default of '127.0.0.1:11211'. If there are more than one input parameter, the parameters are assumed to be a hash with the following fields: .IP "data" 2 .IX Item "data" .Vb 1 \& data => \*(Aq127.0.0.1:11211,127.0.0.1:11212\*(Aq, \& \& data => [\*(Aq127.0.0.1:11211\*(Aq,\*(Aq127.0.0.1:11212\*(Aq], \& \& data => { \& servers => [\*(Aq127.0.0.1:11211\*(Aq,\*(Aq127.0.0.1:11212\*(Aq], \& debug => 1, \& }, \& \& data => $memcached, .Ve .Sp The specification of the memcached server backend(s) for the \*(L"data server\*(R". It should either be: .Sp .Vb 4 \& \- string with comma separated memcached server specification \& \- list ref with memcached server specification \& \- hash ref with Cache::Memcached object specification \& \- blessed object adhering to the Cache::Memcached API .Ve .Sp There is no default for this field, it \fBmust\fR be specified. The blessed object can later be obtained with the data method. .IP "delimiter" 2 .IX Item "delimiter" .Vb 1 \& delimiter => \*(Aq;\*(Aq, # default: \*(Aq#\*(Aq .Ve .Sp Specify the delimiter to be used in key generation. Should only be specified if you expect key, \s-1ID\s0, version or namespace values to contain the character '#'. Can be any character that will not be part of key, \s-1ID\s0, version or namespace values. .Sp The current delimiter can be obtained with the delimiter method. .Sp Using the null byte (\fI\e\e0\fR) is not advised at this moment, as there are some encoding issues within Cache::Memcached regarding null bytes. .IP "directory" 2 .IX Item "directory" .Vb 1 \& directory => \*(Aq127.0.0.1:11311,127.0.0.1:11312\*(Aq, \& \& directory => [\*(Aq127.0.0.1:11311\*(Aq,\*(Aq127.0.0.1:11312\*(Aq], \& \& directory => { \& servers => [\*(Aq127.0.0.1:11311\*(Aq,\*(Aq127.0.0.1:11312\*(Aq], \& debug => 1, \& }, \& \& directory => $memcached, .Ve .Sp The specification of the memcached server backend(s) for the \&\*(L"directory server\*(R". It should either be: .Sp .Vb 4 \& \- string with comma separated memcached server specification \& \- list ref with memcached server specification \& \- hash ref with Cache::Memcached object specification \& \- blessed object adhering to the Cache::Memcached API .Ve .Sp If this field is not specified, the \*(L"data server\*(R" object will be assumed. The blessed object can later be obtained with the directory method. .IP "expiration" 2 .IX Item "expiration" .Vb 1 \& expiration => \*(Aq1H\*(Aq, # default: \*(Aq1D\*(Aq .Ve .Sp The specification of the default expiration. The following postfixes can be specified: .Sp .Vb 5 \& \- S seconds \& \- M minutes \& \- H hours \& \- D days \& \- W weeks .Ve .Sp The default default expiration is one day ('1D'). The default expiration will be used whenever no expiration has been specified with add, decr, incr, replace or set. The default expiration can be obtained with the expiration method. .IP "flush_interval" 2 .IX Item "flush_interval" .Vb 1 \& flush_interval => 10, # default: none .Ve .Sp The specification of the default interval between which memcached servers will be flushed with flush_all. No interval will be used by default if not specified. .IP "group_names" 2 .IX Item "group_names" .Vb 1 \& group_names => [qw(foo bar)], # default: [\*(Aqgroup\*(Aq] .Ve .Sp The specification of allowable group names. Should be specified as a list reference to the allowable group names. Defaults to one element list reference with 'group' only. .Sp Any group name can be specified, as long it consists of alphanumeric characters and does not interfere with other functions. Currently disallowed name are: .Sp .Vb 7 \& \- data \& \- delete \& \- directory \& \- expiration \& \- id \& \- group_names \& \- namespace .Ve .Sp There is hardly any penalty for using a lot of different group names in itself. However, linking cached information to a lot of different groups \fBdoes\fR have a penalty. .IP "inactive" 2 .IX Item "inactive" .Vb 1 \& inactive => 1, .Ve .Sp Indicate that the object is inactive. If this is specified, an instantiated object is returned with the same \s-1API\s0 as Cache::Memcached::Managed, but which will not do anything. Intended to be uses in situations where no active memcached servers can be reached: all code will then function as if there are no cached values in the cache. .IP "memcached_class" 2 .IX Item "memcached_class" .Vb 1 \& memcached_class => \*(AqCached::Memcached::Fast\*(Aq, .Ve .Sp By default, this module uses the Cache::Memcached class as a \f(CW\*(C`memcached\*(C'\fR client. Recently, other implementations have been developed, such as Cache::Memcached::Fast, that are considered to be \s-1API\s0 compatible. To be able to use these other implementation of the memcached client, you can specify the name of the class to be used. By default, \f(CW\*(C`Cache::Memcached\*(C'\fR will be assumed: the module will be loaded automatically if not loaded already. .IP "namespace" 2 .IX Item "namespace" .Vb 1 \& namespace => \*(Aqfoo\*(Aq, # default: $> ($EUID) .Ve .Sp The specification of the default namespace to be used with set, incr, decr, add, replace, get, get_multi, group, get_group and grab_group. Defaults to the effective user \s-1ID\s0 of the process, as indicated by $> ($EUID). .SH "OBJECT METHODS" .IX Header "OBJECT METHODS" The following object methods are available (in alphabetical order): .SS "add" .IX Subsection "add" .Vb 1 \& $cache\->add( $value ); \& \& $cache\->add( $value, $id ); \& \& $cache\->add( $value, $id, $expiration ); \& \& $cache\->add( value => $value, \& id => $id, # optional \& key => $key, # optional \& group => \*(Aqfoo\*(Aq, # optional \& expiration => \*(Aq3H\*(Aq, # optional \& version => \*(Aq1.0\*(Aq, # optional \& namespace => \*(Aqfoo\*(Aq, # optional \& ); .Ve .PP Add a value to the cache, but only if it doesn't exist yet. Otherwise the same as set. .SS "data" .IX Subsection "data" .Vb 1 \& my $data = $cache\->data; .Ve .PP Returns the data server object as specified with new. .SS "dead" .IX Subsection "dead" .Vb 1 \& my @dead = $cache\->dead; \& \& my $dead = $cache\->dead; # hash ref .Ve .PP Returns the memcached backend servers that appear to be non-functional. In list context returns the specifications of the servers in alphabetical order. Returns a hash reference in scalar context, where the unresponsive servers are the keys. Call errors to obtain the number of errors that were found for each memcached server. .SS "decr" .IX Subsection "decr" .Vb 1 \& $cache\->decr; \& \& $cache\->decr( $value ); \& \& $cache\->decr( $value, $id, $expiration ); \& \& $cache\->decr( value => $value, # default: 1 \& id => $id, # default: key only \& key => $key, # default: caller environment \& expiration => \*(Aq3H\*(Aq, # default: $cache\->expiration \& version => \*(Aq1.0\*(Aq, # default: key environment \& namespace => \*(Aqfoo\*(Aq, # default: $cache\->namespace \& ); .Ve .PP Decrement a value to the cache, but only if it already exists. Otherwise the same as set. Default for value is \fB1\fR. .PP Please note that any group associations will \fBnever\fR be honoured: it is assumed they would be all the same for all calls to this counter and are therefore set only with set, add or incr. .SS "delete" .IX Subsection "delete" .Vb 1 \& $cache\->delete; \& \& $cache\->delete( $id ); \& \& $cache\->delete( id => $id, # optional \& key => $key, # optional \& version => \*(Aq1.0\*(Aq, # optional \& namespace => \*(Aqfoo\*(Aq, # optional \& ); .Ve .PP Delete a value, associated with the specified \*(L"data key\*(R", from the cache. Can be called with unnamed and named parameters (assumed if two or more input parameters given). If called with unnamed parameters, then they are: .IP "1 id" 2 .IX Item "1 id" The \s-1ID\s0 to be used to identify the value to be deleted. Defaults to no \s-1ID\s0 (then uses key only). .PP When using named parameters, the following names can be specified: .IP "id" 2 .IX Item "id" The \s-1ID\s0 to be used to identify the value to be deleted. Defaults to no \s-1ID\s0 (then uses key only). .IP "key" 2 .IX Item "key" The key to be used to identify the value to be deleted. Defaults to the default key (as determined by the caller environment). .IP "version" 2 .IX Item "version" The version to be used to identify the value to be deleted. Defaults to the version associated with the key. .IP "namespace" 2 .IX Item "namespace" The namespace to be used to identify the value to be deleted. Defaults to the default namespace associated with the object. .SS "delete_group" .IX Subsection "delete_group" .Vb 1 \& my $deleted = $cache\->delete_group( group => \*(Aqfoo\*(Aq ); .Ve .PP Deletes all cached information related to one or more given groups (specified as name and \s-1ID\s0 value pairs) and returns how many items were actually deleted. .SS "delimiter" .IX Subsection "delimiter" .Vb 1 \& my $delimiter = $cache\->delimiter; .Ve .PP Returns the delimiter as (implicitly) specified with new. .SS "directory" .IX Subsection "directory" .Vb 1 \& my $directory = $cache\->directory; .Ve .PP Returns the directory cache object as (implicitly) specified with new. .SS "errors" .IX Subsection "errors" .Vb 4 \& my $errors = $cache\->errors( "reset" ); \& foreach ($cache\->servers) { \& print "Found $errors\->{$_} errors for $_\en" if exists $errors\->{$_}; \& } .Ve .PP Return a hash reference with the number of errors when storing data values in a memcached backend server. Use dead to find out whether a server is not responding. A true value for the input parameter indicates that the error counts should be reset. .SS "expiration" .IX Subsection "expiration" .Vb 1 \& $expiration = $cache\->expiration; .Ve .PP Returns the default expiration as (implicitly) specified with new. .SS "flush_all" .IX Subsection "flush_all" .Vb 1 \& my $flushed = $cache\->flush_all; \& \& my $flushed = $cache\->flush_all( 30 ); # flush with 30 second intervals .Ve .PP Initialize contents of all of the memcached backend servers of the \&\*(L"data server\*(R". The input parameter specifies interval between flushes of backend memcached servers, default is the flush_interval value implicitly) specified with new. Returns whether all memcached servers were successfully flushed. .PP Please note that this method returns immediately after instructing each of the memcached servers. Also note that the timed flush_all functionality has only recently become part of the standard memcached \s-1API\s0 (starting from publicly released version \f(CW1.2.1\fR). See the file \*(L"flush_interval.patch\*(R" for a patch for release 1.1.12 of the memcached software that implements timed flush_all functionality. .SS "flush_interval" .IX Subsection "flush_interval" .Vb 1 \& my $interval = $cache\->flush_interval; .Ve .PP Returns the default flush interval values used with flush_all, as (implicitly) specified with new. .SS "get" .IX Subsection "get" .Vb 1 \& my $value = $cache\->get; \& \& my $value = $cache\->get( $id ); \& \& my $value = $cache\->get( id => $id, # optional \& key => $key, # optional \& version => \*(Aq1.1\*(Aq, # optional \& namespace => \*(Aqfoo\*(Aq, # optional \& ); .Ve .PP Obtain a value, associated with a \*(L"data key\*(R", from the cache. Can be called with unnamed and named parameters. If called with unnamed parameters, then these are: .IP "1 id" 2 .IX Item "1 id" The \s-1ID\s0 to be used to identify the value to be fetched. Defaults to no \s-1ID\s0 (then uses the default key only). .PP When using named parameters, the following names can be specified: .IP "id" 2 .IX Item "id" The \s-1ID\s0 to be used to identify the value to be fetched. Defaults to no \s-1ID\s0 (then uses key only). .IP "key" 2 .IX Item "key" The key to be used to identify the value to be fetched. Defaults to the default key (as determined by the caller environment). .IP "version" 2 .IX Item "version" The version to be used to identify the value to be deleted. Defaults to the version associated with the key. .IP "namespace" 2 .IX Item "namespace" The namespace to be used to identify the value to be deleted. Defaults to the default namespace associated with the object. .SS "get_group" .IX Subsection "get_group" .Vb 10 \& my $group = $cache\->get_group( \& group => $groupname, \& namespace => $namespace, # default: $cache\->namespace \& ); \& foreach my $key (sort keys %{$group}) { \& print "key: $key\en" \& my $versions = $group\->{$key}; \& foreach my $version (sort keys %{$versions}) { \& print " version: $version\en"; \& my $ids = $versions\->{$version}; \& foreach my $id (sort keys %{$ids}) { \& print " id: $ids\->{$id}\en"; \& } \& } \& } \& \& my @value = $cache\->get_group( \& group => $groupname, \& namespace => $namespace, # default: $cache\->namespace \& ); .Ve .PP Either returns a reference to a multi level hash for the given group name and \&\s-1ID\s0 (containing the group's data) in scalar context, or a list with values (regardless of key, version or id) in list context. .PP The input parameters are a hash that should contain the group name and associated \s-1ID,\s0 with an optional namespace specification. .PP The structure of the returned hash reference is: .PP .Vb 5 \& $result \& |\-\-\- key \& |\-\- version \& |\-\- id \& |\-\- value .Ve .PP See \*(L"group management\*(R" for more information about groups. See grab_group for obtaining the group and deleting it at the same time. .SS "get_multi" .IX Subsection "get_multi" .Vb 1 \& my $hash = $cache\->get_multi( \e@id ); \& \& my $hash = $cache\->get_multi( \& id => \e@id, \& key => $key, \& namespace => $namespace, \& ); .Ve .PP Optimized way of obtaining multiple values, associated with the same key, from the cache. Returns a hash reference with values found, keyed to the associated \s-1ID\s0. .PP Can be called with named and unnamed parameters. If called with unnamed parameters, the parameters are: .IP "1 id" 2 .IX Item "1 id" A list reference of \s-1ID\s0's to be used to identify the values to be fetched. Must be specified. .PP When using named parameters, the following names can be specified: .IP "id" 2 .IX Item "id" A list reference of \s-1ID\s0's to be used to identify the values to be fetched. Must be specified. .IP "key" 2 .IX Item "key" The key to be used to identify the values to be fetched. Defaults to the default key (as determined by the caller environment). .IP "namespace" 2 .IX Item "namespace" The namespace for which to fetch values. Defaults to the namespace that was (implicitly) specified with new. .SS "grab_group" .IX Subsection "grab_group" .Vb 4 \& my $group = $cache\->grab_group( \& group => $groupname, \& namespace => $namespace, # default: $cache\->namespace \& ); .Ve .PP Same as get_group, but removes the returned data from the cache at the same time. .SS "group" .IX Subsection "group" .Vb 8 \& my $group = $cache\->group( \& group => $groupname, \& namespace => $namespace, # default: $cache\->namespace \& ); \& foreach my $key (sort keys %{$group}) { \& print "key: $key\en" \& print " ids: @{$group\->{$key}}\en"; \& } .Ve .PP Return a reference to a multi level hash for the given group name and \s-1ID.\s0 The input parameters are a hash that should contain the group name and associated \s-1ID,\s0 with an optional namespace specification. .PP The structure of the hash is: .PP .Vb 3 \& $result \& |\-\-\- key \& |\-\-\- [id1,id2..idN] .Ve .PP See \*(L"group management\*(R" for more information about groups. .SS "group_names" .IX Subsection "group_names" .Vb 1 \& my @group_name = $cache\->group_names; \& \& my $group_names = $cache\->group_names; # hash ref .Ve .PP Returns the valid group names as (implicitly) specified with new. Returns them in alphabetical order if called in a list context, or as a hash ref if called in scalar context. .SS "inactive" .IX Subsection "inactive" .Vb 1 \& print "Inactive!\en" if $cache\->inactive; .Ve .PP Returns whether the cache object is inactive. This happens if a true value is specified with new. .SS "incr" .IX Subsection "incr" .Vb 1 \& $cache\->incr; \& \& $cache\->incr( $value ); \& \& $cache\->incr( $value, $id ); \& \& $cache\->incr( $value, $id, $expiration ); \& \& $cache\->incr( value => $value, # default: 1 \& id => $id, # default: key only \& key => $key, # default: caller environment \& expiration => \*(Aq3H\*(Aq, # default: $cache\->expiration \& version => \*(Aq1.1\*(Aq, # default: key environment \& namespace => \*(Aqfoo\*(Aq, # default: $cache\->namespace \& group => \*(Aqbar\*(Aq, # default: none \& ); .Ve .PP Increment a value to the cache. Otherwise the same as set. Default for value is \fB1\fR. .PP Differently from the \fBincr()\fR of Cache::Memcached, this increment function is magical in the sense that it automagically will add the counter if it doesn't exist yet. .PP Please note that any group associations will only be set when the counter is created (and will be ignored in any subsequent increments of the same counter). .SS "namespace" .IX Subsection "namespace" .Vb 1 \& my $namespace = $cache\->namespace; .Ve .PP Obtain the default namespace, as (implicitly) specified with new. .SS "replace" .IX Subsection "replace" .Vb 1 \& $cache\->replace( $value ); \& \& $cache\->replace( $value, $id ); \& \& $cache\->replace( $value, $id, $expiration ); \& \& $cache\->replace( value => $value, # undef \& id => $id, # default: key only \& key => $key, # default: caller environment \& expiration => \*(Aq3H\*(Aq, # default: $cache\->expiration \& version => \*(Aq1.1\*(Aq, # default: key environment \& namespace => \*(Aqfoo\*(Aq, # default: $cache\->namespace \& ); .Ve .PP Replace a value to the cache, but only if it already exists. Otherwise the same as set. .PP Please note that any group associations will \fBnever\fR be honoured: it is assumed they would be all the same for all calls to this counter and are therefore set only with set, add or incr. .SS "reset" .IX Subsection "reset" .Vb 1 \& $cache\->reset; .Ve .PP Resets the client side of the cache system. Mainly for internal usage only. Always returns true. .SS "servers" .IX Subsection "servers" .Vb 1 \& my @backend = $cache\->servers; \& \& my $backend = $cache\->servers; # hash ref .Ve .PP Returns the configuration details of the memcached backend servers that are currently configured to be used. Returns a list in alphabetical order in list context, and a hash ref in scalar context. .PP See also dead to find out if any of the memcached backend servers are not responding. .SS "set" .IX Subsection "set" .Vb 1 \& $cache\->set; \& \& $cache\->set( $value ); \& \& $cache\->set( $value,$id ); \& \& $cache\->set( $value, $id, $expiration ); \& \& $cache\->set( value => $value, # default: undef \& id => $id, # default: key only \& key => $key, # default: caller environment \& expiration => \*(Aq3H\*(Aq, # default: $cache\->expiration \& version => \*(Aq1.1\*(Aq, # default: key environment \& namespace => \*(Aqfoo\*(Aq, # default: $cache\->namespace \& group => \*(Aqbar\*(Aq, # default: none \& ); .Ve .PP Set a value in the cache, regardless of whether it exists already or not. .PP Can be called with named or unnamed parameters (if called with two input parameters or less). If called with unnamed parameters, then the input parameters are: .IP "1 value" 2 .IX Item "1 value" The value to set in the cache. Defaults to \f(CW\*(C`undef\*(C'\fR. .IP "2 id" 2 .IX Item "2 id" The \s-1ID\s0 to be used to identify the value. Defaults to no \s-1ID\s0 (then uses key only). .IP "3 expiration" 2 .IX Item "3 expiration" The expiration of the value. Defaults to the value as specified with expiration for the key. .PP With named input parameters, the following names and values can be specified as a hash (in alphabetical order). .IP "expiration" 2 .IX Item "expiration" The expiration time in seconds of the given value. Defaults to the value as specified with expiration for the key. Values below 30*24*60*60 (30 days) will be considered to be relative to the current time. Other values will be assumed to be absolute epoch times (seconds since 1 Jan. 1970 \s-1GMT\s0). See \*(L"expiration specification\*(R" for more ways to set expiration. .IP "id" 2 .IX Item "id" The \s-1ID\s0 to be used to identify the value. Defaults to no \s-1ID\s0 (then uses key only). .IP "key" 2 .IX Item "key" The key to be used to identify the value. Defaults to the default key (as determined by the caller environment). Can be specified as a relative key when prefixed with \*(L"::\*(R", so that \*(L"::bar\*(R" would refer to the key \*(L"Foo::bar\*(R" if called from the package \*(L"Foo\*(R". .IP "namespace" 2 .IX Item "namespace" The namespace to which to associate the value. Defaults to the namespace that was (implicitly) specified with new. .IP "value" 2 .IX Item "value" The value to set in the cache. Defaults to \f(CW\*(C`undef\*(C'\fR. .IP "version" 2 .IX Item "version" The version to be used to identify the value to be set. Defaults to the version associated with the key. .PP Other than these named parameters, any number of group name and \s-1ID\s0 pairs can be specified to indicate a link to that group. .SS "start" .IX Subsection "start" .Vb 1 \& my $started_ok = $cache\->start; \& \& my $started_ok = $cache\->start( $config ); .Ve .PP Attempts to start the memcached servers that have been configured with new (and which can be find out with servers) by default, or the servers with the specified configs. Returns whether all servers (implicitly) specified have been started successfully. .PP This only works if the memcached server(s) will be running on the same physical hardware as the script is running (which will generally not be the case in a production environment). It is therefore of limited usage generally, but it is a handy feature to have if you're developing or testing. .PP See also stop. .SS "stats" .IX Subsection "stats" .Vb 1 \& my $stats = $cache\->stats; .Ve .PP Return a hash ref with simple statistics of all of the memcached backend servers. The structure of the hash ref is as follows: .PP .Vb 4 \& $stats \& |\-\- server specification \& |\-\- key \& |\-\- value .Ve .PP See the memcached server documentation on possible keys and values. .SS "stop" .IX Subsection "stop" .Vb 1 \& my $stopped = $cache\->stop; \& \& my $stopped = $cache\->stop( $config ); .Ve .PP Attempts to stop the specified memcached servers (as specified by config value), returns whether all servers have actually stopped. Defaults to stopping all servers as initially specified with new. .PP This only works if the memcached server(s) are running on the same physical hardware as the script is running (which will generally not be the case in a production environment). It is therefore of limited usage generally, but it is a handy feature to have if you're developing or testing. .PP See also start. .SS "version" .IX Subsection "version" .Vb 1 \& my $version = $cache\->version; # hash ref \& \& my $version = $cache\->version( $config ); # hash ref .Ve .PP Obtain the version information of the specified memcached servers, or all memcached servers being used if no input parameters are specified. Returns a hash reference in which the keys are the config information of the servers used (as returned by servers) and the values are the version information of the associated memcached server. .SH "EXAMPLES" .IX Header "EXAMPLES" .SS "generic grouped event logging" .IX Subsection "generic grouped event logging" .Vb 4 \& $cache\->set( group => \*(Aqevent1\*(Aq, \& id => \*(Aq:unique\*(Aq, \& value => $value \& ); .Ve .PP This would put the value \f(CW$value\fR into the cache, linked to the group \&'event1'. Since we're not interested in the id of the event, but want to make sure it is always unique, the pseudo id ':unique' is specified. .PP A recurring process, usually a cron job, would then need to do the following to grab all of the values cached: .PP .Vb 4 \& my @value = $cache\->grab_group( group => \*(Aqevent1\*(Aq ); \& foreach (@value) { \& # perform whatever you want to do with the value in C<$_> \& } .Ve .PP Please not that only the values are returned because grab_group is called in list context. .SS "generic content logging" .IX Subsection "generic content logging" .Vb 10 \& my $cache = Cache::Memcached::Managed\->new( \& data => $servers, \& group_names => [qw(hotel_id room_id)], \& expiration => \*(Aq1H\*(Aq, \& ); \& package Foo; \& sub available { \& my ($cache,$hotel_id,$room_id,$checkin,$checkout) = @_; \& my $available; \& unless ($available = $cache\->get( id => [$room_id,$checkin,$checkout] )) { \& # perform complicated calculations setting C<$available> \& $cache\->set( id => [$room_id,$checkin,$checkout], \& value => $available, \& room_id => $room_id, \& hotel_id => $hotel_id, \& ); \& } \& return $available; \& } #available .Ve .PP This example shows availability caching in a specific subroutine. Because the get and the set are located in de same subroutine, it is not necessary to specify the key (which will be automatically set to \&\*(L"Foo::available\*(R"). .PP Please also not the absence of a namespace specification. Since each user of the \*(L"available\*(R" subroutine should have its \*(L"realm\*(R" depending on the cache object, no namespace specification is done. .PP Now, whenever something related to the hotel_id is changed, a simple: .PP .Vb 1 \& $cache\->delete_group( hotel_id => $hotel_id ); .Ve .PP would be enough to also remove any availability cached in the above example (for the same value of \f(CW$hotel_id\fR). .PP The same would apply when something related to the room_id is changed: a simple: .PP .Vb 1 \& $cache\->delete_group( room_id => $room_id ); .Ve .PP would be enough to also remove any availability cached in the above example (for the same value of \f(CW$room_id\fR). .SH "CAVEATS" .IX Header "CAVEATS" .SS "Race Conditions" .IX Subsection "Race Conditions" Several race conditions exists that can not be fixed because of a lack of semaphores when using memcached. .PP Most important race condition is when a group is deleted: between the moment the main pointer (\*(L"directory key\*(R") is reset and all of the index keys are removed, it is possible for another process to be adding information to the same directory key already. In a worst case scenario, this means that a data key can get lost. .PP To prevent this, a delay of \fB2\fR seconds is applied to each time a group is deleted. This should give some time for the cleaning process to clean up before other processes start accessing again, but it is no way a guarantee that other processes wouldn't be able to add information if the cleaning process needs more than 2 seconds to clean up. .SS "Cron jobs" .IX Subsection "Cron jobs" Because the \*(L"data key\*(R"s by default includes the user id (uid) of the process as the namespace with which the entry was stored in the cache, cron jobs (which usually run under a different user id) will need to set the namespace to the user id of the process storing information into the cache. .SS "Incompatibility with Cache module" .IX Subsection "Incompatibility with Cache module" John Goulah pointed out to me that there is an inconsistency with unnamed parameter passing in respect to the Cache module. Specifically, the \&\f(CW\*(C`set\*(C'\fR method: .PP .Vb 1 \& $c\->set( $key, $data, [ $expiry ] ); .Ve .PP is incompatible with this module's \f(CW\*(C`set\*(C'\fR method: .PP .Vb 1 \& $cache\->set; \& \& $cache\->set( $value ); \& \& $cache\->set( $value, $id ); \& \& $cache\->set( $value, $id, $expiration ); .Ve .PP The reason for this simple: in this module, \fBall\fR parameters are optional. So you can specify just a value: the key will be generated for you from the caller environment. Since I felt at the time that you would more likely specify a value than a key, I made that the first parameter (as opposed to the \f(CW\*(C`set\*(C'\fR method of Cache. Changing to the format as imposed by the Cache module, is not an option at this moment in the lifetime of this module, as it would break existing code (the same way as it breaks the test-suite). .SH "THEORY OF OPERATION" .IX Header "THEORY OF OPERATION" The group management is implemented by keeping a type of directory information in a (separate) directory memcached server. .PP For each group one directory key is maintained in the directory memcached server. This key consists of the string \&\*(L"Cache::Memcached::Managed::\*(R", appended with the namespace, group name, the delimiter and the \s-1ID\s0 of the group. For instance, the directory key for the group .PP .Vb 1 \& group => \*(Aqfoo\*(Aq .Ve .PP when running as user \*(L"500\*(R" would be: .PP .Vb 1 \& Cache::Memcached::Managed#500#group#foo .Ve .PP The value of the directory key of a group is used as a counter. Each time a some content is added that is linked to the group, that counter will be incremented and its value prepended to create an \f(CW"index key"\fR. So the first index key of the above example, would be: .PP .Vb 1 \& 1#Cache::Memcached::Managed#500#group#foo .Ve .PP This index key is then also stored in the directory memcached server, with the original \*(L"data key\*(R" as its value, and with the same expiration as used for the data key. .PP Whenever the index keys are needed of a group (e.g. for fetching all of its members, or for deleting all of its members), the value of the directory key of the group is inspected, and that is used to generate a list of index keys. Suppose the value of the directory key is 5, then then following index keys would be generated (essentially mapping 1..5): .PP .Vb 5 \& 1#Cache::Memcached::Managed#500#group#foo \& 2#Cache::Memcached::Managed#500#group#foo \& 3#Cache::Memcached::Managed#500#group#foo \& 4#Cache::Memcached::Managed#500#group#foo \& 5#Cache::Memcached::Managed#500#group#foo .Ve .PP If the group is to be deleted or fetched, then all possible values for these index keys are obtained. For instance, this would fetch: .PP .Vb 5 \& 1#Cache::Memcached::Managed#500#group#foo => 500#1.0#Foo::zip#23 \& 2#Cache::Memcached::Managed#500#group#foo => 500#1.1#Bar::pod#47 \& 3#Cache::Memcached::Managed#500#group#foo => 500#1.0#Foo::zip#23 \& 4#Cache::Memcached::Managed#500#group#foo => 500#1.1#Bar::pid#12 \& 5#Cache::Memcached::Managed#500#group#foo => 500#1.1#Bar::pid#14 .Ve .PP Note that index key 1 and 3 return the same backend key. This can be caused by doing multiple sets with the same key / id combination. The final list of backend keys then becomes: .PP .Vb 4 \& 500#1.0#Foo::zip#23 \& 500#1.1#Bar::pod#47 \& 500#1.1#Bar::pid#12 \& 500#1.1#Bar::pid#14 .Ve .PP If the group is to be deleted (delete_group), then the index keys are removed from the directory memcached server. And the associated data keys are removed from the data memcached server. .PP If the group (data) is to be fetched (group or get_group), then the superfluous index keys are removed from the directory memcached server. In this example, that would be: .PP .Vb 1 \& 1#Cache::Memcached::Managed#500#group#foo .Ve .PP because: .PP .Vb 1 \& 3#Cache::Memcached::Managed#500#group#foo .Ve .PP also refers to the data key .PP .Vb 1 \& 500#1.0#Foo::zip#23 .Ve .PP Because of this, the lowest index key with a valid data key has become: .PP .Vb 1 \& 2#Cache::Memcached::Managed#500#group#foo .Ve .PP making \*(L"2\*(R" the lowest ordinal number of the index keys. In that case a special key, the lowest index key, is saved in the directory memcached server. The name of the keys is the same as the directory key for the group, postfixed with the delimiter and the string \*(L"_lowest\*(R". In this example, this would be: .PP .Vb 1 \& Cache::Memcached::Managed#500#group#foo#_lowest .Ve .PP Whenever index keys are fetched, the value of this key is used to determine the start point for the generation of index keys. If, in the above example another fetch of that group would be done, then these index_keys would be generated (essentially mapping 2..5): .PP .Vb 4 \& 2#Cache::Memcached::Managed#500#group#foo \& 3#Cache::Memcached::Managed#500#group#foo \& 4#Cache::Memcached::Managed#500#group#foo \& 5#Cache::Memcached::Managed#500#group#foo .Ve .PP Since 32 bit counters are being used, about 4 billion items can be linked to a group, before a group should be deleted to completely restart. In most live situation, this overflow condition will not occur, since this mechanism was mainly intended to be able to delete groups of information from the cache. And a deletion will remove the counter and all of its associated keys, essentially starting again at 1. .SH "REQUIRED MODULES" .IX Header "REQUIRED MODULES" .Vb 2 \& Cache::Memcached (any) \& Scalar::Util (any) .Ve .SH "AUTHOR" .IX Header "AUTHOR" .Vb 1 \& Elizabeth Mattijsen .Ve .PP maintained by \s-1LNATION,\s0 .SH "HISTORY" .IX Header "HISTORY" This module started life as an internal module at \s-1BOOKINGS\s0 Online Hotel Reservation, the foremost European on-line hotel booking portal. With approval and funding of Bookings, this module was generalized and put on \&\s-1CPAN,\s0 for which Elizabeth Mattijsen would like to express her gratitude. .SH "COPYRIGHT" .IX Header "COPYRIGHT" (C) 2005, 2006 \s-1BOOKINGS\s0 (C) 2007, 2008 \s-1BOOKING.COM\s0 (C) 2012 Elizabeth Mattijsen .PP This program is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. .PP This program is distributed in the hope that it will be useful, but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \&\s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place \- Suite 330, Boston, \s-1MA\s0 02111\-1307, \s-1USA.\s0