Rose::DB::Cache(3pm) | User Contributed Perl Documentation | Rose::DB::Cache(3pm) |
Rose::DB::Cache - A mod_perl-aware cache for Rose::DB objects.
# Usage package My::DB; use base 'Rose::DB'; ... $cache = My::DB->db_cache; $db = $cache->get_db(...); $cache->set_db($db); $cache->clear; # Subclassing package My::DB::Cache; use Rose::DB::Cache; our @ISA = qw(Rose::DB::Cache); # Override methods as desired sub get_db { ... } sub set_db { ... } sub prepare_db { ... } sub build_cache_key { ... } sub clear { ... } ...
Rose::DB::Cache provides both an API and a default implementation of a caching system for Rose::DB objects. Each Rose::DB-derived class references a Rose::DB::Cache-derived object to which it delegates cache-related activities. See the new_or_cached method for an example.
The default implementation caches and returns Rose::DB objects using the combination of their type and domain as the cache key. There is no cache expiration or other cache cleaning.
The only sophistication in the default implementation is that it is mod_perl- and Apache::DBI-aware. When running under mod_perl, with or without Apache::DBI, the dbh attribute of each cached Rose::DB object is set to "undef" at the end of each request. Additionally, any db connections made in a pre-fork parent apache process are not cached.
When running under Apache::DBI, the behavior described above will ensure that Apache::DBI's "ping" and rollback features work as expected, keeping the DBI database handles contained within each Rose::DB object connected and alive.
When running under mod_perl without Apache::DBI, the behavior described above will use a single DBI database connection per cached Rose::DB object per request, but will discard these connections at the end of each request.
Both mod_perl 1.x and 2.x are supported. Under mod_perl 2.x, you should load Rose::DB on server startup (e.g., in your "startup.pl" file). If this is not possible, then you must explicitly tell Rose::DB::Cache that apache has started up already by setting apache_has_started to a true value.
Subclasses can override any and all methods described below in order to implement their own caching strategy.
If a cached object is found, the prepare_db method is called, passing the cached db object and its corresponding Rose::DB::Cache::Entry object as arguments. The cached db object is then returned.
If no such object exists in the cache, undef is returned.
When NOT running under mod_perl, this method does nothing.
When running under mod_perl (version 1.x or 2.x), this method will do the following:
Putting all the pieces together, the following implementation of the init_db method in your Rose::DB::Object-derived common base class will ensure that database connections are shared and fresh under mod_perl and (optionally) Apache::DBI, but unshared elsewhere:
package My::DB::Object; use base 'Rose::DB::Object'; use My::DB; # isa Rose::DB ... BEGIN: { if($ENV{'MOD_PERL'}) { *init_db = sub { My::DB->new_or_cached }; } else # act "normally" when not under mod_perl { *init_db = sub { My::DB->new }; } }
If running under mod_perl and the apache server is starting up and use_cache_during_apache_startup is set to true, then the DB object is not added to the cache, but merely returned.
DBI database handles created in the parent apache process cannot be used in child apache processes. Furthermore, in the case of at least one one DBI driver class, you must also ensure that any database handles created in the apache parent process during server startup are properly disconnect()ed before you fork off the first apache child. Failure to do so may cause segmentation faults(!) in child apache processes.
The upshot is that if use_cache_during_apache_startup is set to true, you should call prepare_for_apache_fork at the very end of the apache startup process (i.e., once all other Perl modules have been loaded and all other Perl code has run). This is usually done by placing a call at the bottom of the traditional "startup.pl" file. Assuming "My::DB" is your Rose::DB-derived class:
My::DB->db_cache->prepare_for_apache_fork();
A convenience method exists in Rose::DB as well, which simply translates into call shown above:
My::DB->prepare_cache_for_apache_fork();
John C. Siracusa (siracusa@gmail.com)
Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
2023-03-04 | perl v5.36.0 |