The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

PSA::Cache - Cache of compiled scripts

SYNOPSIS

    my $cache = new PSA::Cache
    (
     base_dir => "psa-bin/",
     default_type => {
                      '\.psa$' => "PSA",
                      '\.pl$' => "Perl",
                     },
     includes_dirs => [ "/usr/lib/psa/bin",
                        "/usr/local/lib/libfoo-psa/" ],
    )

    $cache->run("script.psa", @args);

DESCRIPTION

The PSA Cache is a useful tool for managing large programs built up of several small scripts.

PSA `scripts' are much like calling a function, except that preprocessing can be performed (without having to meddle with Perl source filters), and if the file is changed on the disk, the function will be re-loaded, without having to restart the entire server.

The PSA::Cache is inherantly designed for imperative styles of coding. Run this, call this include, etc. It is equivalent to modules like Apache::Registry for basic mod_perl installations, or the method of using Module::Reload with imperative-style methods of objects, such as Apache Handlers in mod_perl.

Perhaps the best way to get a feel for it is to browse the sample applications, in examples/ in the PSA distribution.

The way it works under the hood is this:

  • The script is preprocessed to a piece of perl, that must return a CODE reference (ie, it simply declares a subroutine). This preprocessing is performed by PSA::Cache::Entry or a sub-class as selected by default_type.

  • That script is placed in its own package/namespace, and then eval()'d into a compiled piece of perl. Whilst I haven't got this working with the Safe module yet (see Safe), this is a handy place to put such a hook, which would give the whole system that extra level of security if you can't trust the components to be behaved. Normally this is locking the door after the horse has bolted, though.

  • When you call $cache-run("script", @args)>, that script is looked up, possibly stat (see perlfunc) is called to see if the file has changed since we last called it, and then the code ref is called with the arguments you pass.

OBJECT PROPERTIES

The PSA::Cache object has several properties useful for configuring the cache. These can be set in any of the styles accepted by Class::Tangram, such as passing to ->new(), ->set(), or by calling the auto-generated accessor/mutators ->property(), ->get_property() and/or ->set_property.

Using the standard psa script, these can be configured in the cache: top level config key;

 cache:
   base_dir: psa-bin/
   index: handler.pl
   includes_dirs:
      - inc/*/psa-bin
      - '/abc/local/share/psa'
base_dir

This option is always required, so must be passed when the object is constructed. This is the "primary" directory to find psa-bin scriptlets.

index

Specify the name for index/fallback scriptlets. Defaults to index.pl

cwd

Specify the working directory for this PSA cache. This is changed to before all operations relating to this cache. Defaults to the current working directory.

default_type

This is a hash from a regular expression applied to a file found in the Cache (or an included location somewhere). The target of the cache is taken to be a package name, with PSA::Cache::Entry:: prepended to it if doesn't have any :: delimiters in it.

These are `handlers' for different styles of scripts. Normally, you just want to the Perl handler, implemented by PSA::Cache::Entry::Perl. There is also a default PSA::Cache::Entry::PSA for those that like to combine the controller + view components of an application, PHP style. This is a much more rapid development method, but in practice has been discovered to be an ultimately flawed approach in the long run.

include_dirs

Specifies a list of paths to check for after fully checking the base_dir.

This can be set to auto, which means to look for inc/*/psa-bin once at startup, and also to scan @INC for likely places for stock scripts to have been delivered.

max_size

Start cycling out LRU cache entries after it gets this big. Sadly, though, closures seldom actually end up freeing application space so this is by default disabled, and not even implemented yet. TO-DO.

stat_age

Don't bother checking files in the cache for changes more often than this number of seconds; defaults to a fairly leisurely 10 seconds.

Make this much higher to avoid unnecessary system calls.

SEE ALSO

PSA, PSA::Cache::Entry, PSA::Cache::Entry::Perl, PSA::Cache::Entry::PSA