Subject: | Workflow::State Persistence |
Date: | Mon, 04 May 2009 15:42:09 -0700 |
To: | bug-Workflow [...] rt.cpan.org |
From: | Andrew Peebles <peebles [...] cortina-systems.com> |
I am using Workflow-1.32 in a web application using FastCGI (Catalyst),
which means the application server (the perl program using Workflow) is
persistent across calls from user clients ... this is for performance
... the application should still behave as if it were running under CGI
from a programmer's point of view.
Anyway, I am seeing what I think is an issue with using Workflow under these circumstances. The package BTW is truly awesome; the best in this category that I have seen.
The problem is that
'No access to action 'Finished Editing' in state 'INITIAL' because cached condition 'IsOwner' already failed before.'
It took me a while to track this down. My "fix" is to install an Observer on "create" and "fetch" that:
sub update {
my ( $class, $wf, $event, $new_state ) = @_;
return unless( $event eq 'fetch' ||
$event eq 'create' );
foreach my $state ( keys( %{$wf->{_states}} ) ) {
$wf->{_states}->{$state}->clear_condition_cache();
}
}
Unfortunately I must peek into internal data structures to do this. I am pretty sure this solution is valid for my application ... which should essentially act like a CGI, in that from a programmers model point of view, should be completely torn down and restarted on each client connection. That would mean that there would be no chance for Workflow::State internal, dynamic variables to bleed across workflow "fetches".
I am thinking that the workflow list of states, when a workflow is created or fetched, should be "clean", possibly a copy of the original list created by the Factory instead of a reference to a single list.
Anyway, I am seeing what I think is an issue with using Workflow under these circumstances. The package BTW is truly awesome; the best in this category that I have seen.
The problem is that
- Workflow::State remembers past condition checks via $self->{'_condition_result_cache'}
- Factory creates once, and remembers the list of Workflow::State objects for a Workflow, and attaches this persistent list (_workflow_states) to workflows when created or fetched.
'No access to action 'Finished Editing' in state 'INITIAL' because cached condition 'IsOwner' already failed before.'
It took me a while to track this down. My "fix" is to install an Observer on "create" and "fetch" that:
sub update {
my ( $class, $wf, $event, $new_state ) = @_;
return unless( $event eq 'fetch' ||
$event eq 'create' );
foreach my $state ( keys( %{$wf->{_states}} ) ) {
$wf->{_states}->{$state}->clear_condition_cache();
}
}
Unfortunately I must peek into internal data structures to do this. I am pretty sure this solution is valid for my application ... which should essentially act like a CGI, in that from a programmers model point of view, should be completely torn down and restarted on each client connection. That would mean that there would be no chance for Workflow::State internal, dynamic variables to bleed across workflow "fetches".
I am thinking that the workflow list of states, when a workflow is created or fetched, should be "clean", possibly a copy of the original list created by the Factory instead of a reference to a single list.