CHI-Cascade
view release on metacpan or search on metacpan
636465666768697071727374757677787980818283Key/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
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.
207208209210211212213214215216217218219220221222223224225226227
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:
lib/CHI/Cascade.pm view on Meta::CPAN
444546474849505152535455565758596061626364
}
else
{
croak
qq{The rule's target "$rule->{target}
" is unknown type};
}
}
sub
target_computing {
my
$trg_obj
;
(
$trg_obj
=
$_
[0]->{target_chi}->get(
"t:$_[1]"
) )
? ( ( ${
$_
[2] } =
$trg_obj
->ttl ),
$trg_obj
->locked ? 1 : 0 )
: 0;
}
sub
target_is_actual {
my
(
$self
,
$target
,
$actual_term
) =
@_
;
my
$trg_obj
;
(
$trg_obj
=
$self
->{target_chi}->get(
"t:$target"
) )
?
$trg_obj
->is_actual(
$actual_term
)
lib/CHI/Cascade.pm view on Meta::CPAN
858687888990919293949596979899100101102103104105106107
if
(
$value
);
CHI::Cascade::Value->new(
state
=> CASCADE_NO_CACHE );
}
sub
target_lock {
my
(
$self
,
$rule
) =
@_
;
my
$target
=
$rule
->target;
# If target is already locked - a return
return
if
(
$self
->target_locked(
$rule
) );
my
$trg_obj
;
$trg_obj
= CHI::Cascade::Target->new
unless
( (
$trg_obj
=
$self
->{target_chi}->get(
"t:$target"
) ) );
$trg_obj
->
lock
;
$self
->{target_chi}->set(
"t:$target"
,
$trg_obj
,
$rule
->target_expires(
$trg_obj
) );
$rule
->{run_instance}{target_locks}{
$target
} = 1;
}
lib/CHI/Cascade.pm view on Meta::CPAN
156157158159160161162163164165166167168169170171172173174175176sub
touch {
my
(
$self
,
$target
) =
@_
;
if
(
my
$trg_obj
=
$self
->{target_chi}->get(
"t:$target"
) ) {
$trg_obj
->touch;
$self
->{target_chi}->set(
"t:$target"
,
$trg_obj
,
$self
->find(
$target
)->target_expires(
$trg_obj
) );
}
}
sub
target_locked {
my
(
$self
,
$rule
) =
@_
;
exists
$rule
->{run_instance}{target_locks}{
$rule
->target };
}
sub
recompute {
my
(
$self
,
$rule
,
$target
,
$dep_values
) =
@_
;
die
CHI::Cascade::Value->new(
state
=> CASCADE_DEFERRED )
if
$rule
->{run_instance}{run_opts}{defer};
lib/CHI/Cascade.pm view on Meta::CPAN
250251252253254255256257258259260261262263264265266267268269270
die
$exception
;
}
return
$ret
;
};
$self
->target_lock(
$rule
)
if
!
$self
->target_time(
$target
);
$should_be_recomputed
=
$self
->target_locked(
$rule
);
if
(
defined
$ttl
&&
$ttl
> 0 && !
$should_be_recomputed
) {
$ret_state
= CASCADE_TTL_INVOLVED;
$run_instance
->{ttl} =
$ttl
;
}
else
{
my
(
$rule_ttl
,
$circle_hash
,
$start_time
,
lib/CHI/Cascade.pm view on Meta::CPAN
307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
delete
$run_instance
->{
$circle_hash
}{
$target
}{
$dep_target
};
}
if
(
defined
$min_start_time
) {
$ret_state
= CASCADE_TTL_INVOLVED;
$self
->target_start_ttl(
$rule
,
$min_start_time
);
$run_instance
->{ttl} =
$min_start_time
+
$rule_ttl
- Time::HiRes::
time
;
}
}
if
(
$self
->target_locked(
$rule
) ) {
# We should recompute this target
# So we should recompute values for other dependencies
foreach
$dep_target
(
keys
%dep_values
) {
if
( !
defined
$dep_values
{
$dep_target
}->[1]
|| !
$dep_values
{
$dep_target
}->[1]->is_value )
{
$self
->{stats}{dependencies_lookup}++;
$catcher
->(
sub
{
if
( ! (
$dep_values
{
$dep_target
}->[1] =
$self
->value_ref_if_recomputed(
$dep_values
{
$dep_target
}->[0],
$dep_target
, 1 ) )->is_value ) {
$self
->target_remove(
$dep_target
);
return
1;
}
return
0;
} ) == 1 &&
return
undef
;
}
}
}
return
$self
->recompute(
$rule
,
$target
, {
map
{
$_
=>
$dep_values
{
$_
}->[1]->value }
keys
%dep_values
} )
if
$self
->target_locked(
$rule
);
return
CHI::Cascade::Value->new(
state
=>
$ret_state
);
};
pop
@{
$run_instance
->{target_stack} };
my
$e
= $@;
if
(
$self
->target_locked(
$rule
) ) {
$self
->target_unlock(
$rule
,
$ret
);
}
elsif
(
$run_instance
->{run_opts}{actual_term} && !
$only_from_cache
&&
$run_instance
->{orig_target} eq
$target
) {
$self
->target_actual_stamp(
$rule
,
$ret
);
}
die
$e
if
$e
;
return
$ret
|| CHI::Cascade::Value->new;
}
lib/CHI/Cascade.pm view on Meta::CPAN
551552553554555556557558559560561562563564565566567568569570571572573=item chi
B<Required>. Instance of L<CHI> object. The L<CHI::Cascade> doesn't construct this
object for you. Please create instance of C<CHI> yourself.
=item busy_lock
B<Optional>. Default is I<never>. I<This is not C<busy_lock> option of CHI!>
This is amount of time (to see L<CHI/"DURATION EXPRESSIONS">) 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.
=item target_chi
B<Optional>. This is CHI cache for target markers. Default value is value of
L</chi> option. It can be useful if you use a L<CHI/l1_cache> 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.
=back
lib/CHI/Cascade.pm view on Meta::CPAN
711712713714715716717718719720721722723724725726727728729730731732B<Optional>. You can pass in your code any additional parameters by this option.
These parameters are accessed in your rule's code through
L<CHI::Cascade::Rule/params> method of L<CHI::Cascade::Rule> instance object.
=item busy_lock
B<Optional>. Default is L</busy_lock> of constructor or I<never> if first is not
defined. I<This is not C<busy_lock> option of CHI!> This is amount of time (to
see L<CHI/"DURATION EXPRESSIONS">) 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.
=item recomputed
B<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:
=over
lib/CHI/Cascade/Rule.pm view on Meta::CPAN
747576777879808182838485868788899091929394
if
(
@_
) {
$self
->{value_expires} =
$_
[0];
return
$self
;
}
(
ref
$self
->{value_expires} eq
'CODE'
?
$self
->{value_expires}->(
$self
) :
$self
->{value_expires} ) //
'never'
;
}
sub
target_expires {
my
(
$self
,
$trg_obj
) =
@_
;
$trg_obj
->locked
?
$self
->{busy_lock} ||
$self
->{cascade}{busy_lock} ||
'never'
:
$trg_obj
->expires //
$trg_obj
->expires(
$self
->value_expires );
}
sub
ttl {
my
$self
=
shift
;
return
undef
lib/CHI/Cascade/Target.pm view on Meta::CPAN
67891011121314151617181920212223242526272829303132333435use
Time::HiRes;
sub
new {
my
(
$class
,
%opts
) =
@_
;
bless
{
%opts
},
ref
(
$class
) ||
$class
;
}
sub
lock
{
$_
[0]->{locked} = $$;
}
sub
locked {
exists
$_
[0]->{locked}
and
$_
[0]->{locked};
}
sub
unlock {
delete
$_
[0]->{locked};
}
sub
time
{
$_
[0]->{
time
} || 0;
}
sub
touch {
$_
[0]->{
time
} = Time::HiRes::
time
;
delete
$_
[0]->{finish_time};
delete
$_
[0]->{expires_finish_time};
( run in 0.477 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )