CHI-Cascade
view release on metacpan or search on metacpan
depends => ['unique_name_other1', 'unique_name_other2'],
code => sub {
my ($rule, $target_name, $values_of_depends) = @_;
# $values_of_depends == {
# unique_name_other1 => $value_1,
# unique_name_other2 => $value_2
# }
# $rule->target eq $target_name
# $rule->depends === ['unique_name_other1', 'unique_name_other2']
# $rule->dep_values == $values_of_depends
# $rule->params == { a => 1, b => 2 }
# Now we can calcualte $value
return $value;
},
params => { a => 1, b => 2 }
);
$cascade->rule(
target => 'unique_name_other1',
depends => 'unique_name_other3',
code => sub {
my ($rule, $target_name, $values_of_depends) = @_;
# $values_of_depends == {
# unique_name_other3 => $value_3
# }
# computing here
return $value;
}
);
$value_of_this_target = $cascade->run('unique_name');
DESCRIPTION
This module is the attempt to use a benefits of caching and 'make'
concept. If we have many an expensive tasks (a *computations* or
sometimes here used term as a *recomputing*) and want to cache it we can
split its to small expsnsive tasks and to describe dependencies for
cache items.
This module is experimental yet. I plan to improve it near time but some
things already work. You can take a look for t/* tests as examples.
CONSTRUCTOR
$cascade = CHI::Cascade->new( %options )
This method constructs a new "CHI::Cascade" object and returns it.
Key/value pair arguments may be provided to set up the initial state.
Options are:
chi Required. Instance of CHI object. The CHI::Cascade doesn't construct
this object for you. Please create instance of "CHI" yourself.
busy_lock
Optional. Default is *never*. *This is not "busy_lock" option of
CHI!* This is amount of time (to see "DURATION EXPRESSIONS" in CHI)
until all target locks expire. When a target is to being computing
it is locked. If process which is to be computing target and it will
die or OS will be hangs up we can dead locks and locked target will
never recomputed again. This option helps to avoid it. You can set
up a special busy_lock for rules too.
target_chi
Optional. This is CHI cache for target markers. Default value is
value of "chi" option. It can be useful if you use a "l1_cache" in
CHI option. So you can separate data of targets from target markers
- data will be kept in a file cache and a marker in memory cache for
example.
METHODS
rule( %options )
To add new rule to "CHI::Cascade" object. All rules should be added
before first "run" method
The keys of %options are (options are passed directly in
CHI::Cascade::Rule constructor):
target
Required. A target for "run" and for searching of "depends". It
can be as scalar text or "Regexp" object created through "qr//"
depends
Optional. The scalar, arrayref or coderef values of
dependencies. This is the definition of target(s) from which
this current rule is dependent. If *depends* is:
scalar
It should be plain text of single dependence of this target.
arrayref
An each item of list can be scalar value (exactly matched
target) or code reference. If item is coderef it will be
executed once as $coderef->( $rule, $rule->qr_params ) and
should return a scalar value as current dependence for this
target at runtime (the API for coderef parameters was
changed since v0.16)
coderef
This subroutine will be executed once inside *run* method if
necessary with parameters as: $coderef->( $rule,
<$rule-qr_params|CHI::Cascade::Rule/qr_params >> ) (API was
changed since v0.16). It should return scalar or arrayref.
The returned value is *scalar* it will be considered as
single dependence of this target and the behavior will be
exactly as described for *scalar* in this paragraph. If the
returned value is *arrayref* it will be considered as list
of dependencies for this target and the behavior will be
exactly as described for *arrayref* in this paragraph.
depends_catch
Optional. This is coderef for dependence exceptions. If any
dependence from list of "depends"'s option throws an exception
of type CHI::Cascade::Value by "die" (for example like this
code: "die CHI::Cascade::Value->new->value( { i_have_problem =>
1 } )" ) then the $cascade will execute this code as
"$rule->{depends_catch}->( $this_rule_obj,
$exception_of_dependence, $rule_obj_of_dependence,
$plain_text_target_of_dependence )" and you can do into inside a
following:
main concept of execution code of rules is to have all valid
values (cached or recomputed) of all dependencies before
execution of dependent code.
code
Required. The code reference for computing a value of this
target (a *computational code*). Will be executed if no value in
cache for this target or any dependence or dependences of
dependences and so on will be recomputed. Will be executed as
"$code->( $rule, $target, $hashref_to_value_of_dependencies )"
*(The API of running this code was changed since v0.10)*
If you want to terminate a code and to return immediately from
"run" method and don't want to save a value in cache you can
throw an exception from "code" of type CHI::Cascade::Value. Your
instance of CHI::Cascade::Value can have a value or cannot (a
valid value can be even "undef"!). A "run" method returns either
a value is set by you (through "value" in CHI::Cascade::Value
method) or value from cache or "undef" in other cases. Please to
see CHI::Cascade::Value
If "run" method will have a "defer" option as true this code
will not be executed and you will get a set bit CASCADE_DEFERRED
in "state" bit mask variable. This may useful when you want to
control a target execution.
$rule
An instance of CHI::Cascade::Rule object. You can use it
object as accessor for some current executed target data
(plain text of target, for getting of parameters and so on).
Please to see CHI::Cascade::Rule
$target
The current executed target as plain text for this "code"
$hashref_to_value_of_dependencies
A hash reference of values (values are cleaned values not
CHI::Cascade::Value objects!) of all dependencies for
current target. Keys in this hash are flat strings of
dependecies and values are computed or cached ones.
This module should guarantee that values of dependencies
will be valid values even if value is "undef". This code can
return "undef" value as a valid code return but author
doesn't recommend it. If "CHI::Cascade" could not get a
valid values of all dependencies of current target before
execution of this code the last will not be executed (The
"run" will return "undef").
params
Optional. You can pass in your code any additional parameters by
this option. These parameters are accessed in your rule's code
through "params" in CHI::Cascade::Rule method of
CHI::Cascade::Rule instance object.
busy_lock
Optional. Default is "busy_lock" of constructor or *never* if
first is not defined. *This is not "busy_lock" option of CHI!*
This is amount of time (to see "DURATION EXPRESSIONS" in CHI)
until target lock expires. When a target is to being computed it
is locked. If process which to be recomputing a target and it
will die or OS will be hangs up we can dead locks and locked
target will never recomputed again. This option helps to avoid
it.
recomputed
Optional. This is a computational callback (coderef). If target
of this rule was recomputed this callback will be executed right
away after a recomputed value has been saved in cache. The
callback will be executed as $coderef->( $rule, $target, $value
) where passed parameters are:
$rule
An instance of CHI::Cascade::Rule class. This instance is
recreated for every target searching and recomputing if
need.
$target
A current target as string
$value
The instance of CHI::Cascade::Value class. You can use a
computed value as $value->value
For example you can use this callback for notifying of other
sites that your target's value has been changed and is already
in cache.
value_expires
Optional. Sets an CHI's cache expire value for all future target
markers are created by this rule in notation described in
"DURATION EXPRESSIONS" in CHI. The default is 'never'. It can be
coderef or string scalar format as "DURATION EXPRESSIONS" in
CHI. A coderef should return value in same format.
ttl Optional. An arrayref for min & max intervals of TTL. Example:
"[ 60, 3600 ]" - where the minimum ttl is seconds and the
maximum is 3600 seconds. Targets of this rule will be recomputed
during from 60 up to 3600 seconds from touched time of any
dependence this rule. Please read "CASCADE_TTL_INVOLVED" in
CHI::Cascade::Value too.
run( $target, %options )
This method makes a cascade computation if need and returns value
(value is cleaned value not CHI::Cascade::Value object!) for this
target If any dependence of this target of any dependencies of
dependencies were (re)computed this target will be (re)computed too.
The run method of instance of cascade can be called from other run
method of same instance and from "callref" function inside "depends"
rule's option. This was made possible by creating a separate data
instance for each root call of run method. This can come in handy
when you compute dependencies on the go, which are computed by the
same object (instance) of "cascade".
$target
Required. Plain text string of target.
%options
Optional. And all options are optional too A hash of options.
Valid keys and values are:
( run in 2.432 seconds using v1.01-cache-2.11-cpan-0d23b851a93 )