Another patch from Alexander Klink:
###
Thanks. Here is another patch from the OpenXPKI wishlist, which does the
following:
In OpenXPKI, we use autorun a lot. But we have some situations where we
would like Workflow to autorun if possible, but we don't really mind
if autorunning is not possible. One example of that is that we would
like to move on in our workflow if a forked workflow instance is
finished, but we don't really care if we stop if it is not finished yet
(we can try to execute the only activity every time we look at the
workflow, for example, sort of a "manual autorun").
Until now, we just caught the corresponding workflow exception that
told us that there were no actions available, but I guess this is not
good style, really.
This is why this patch introduces the "may_stop" property for a state,
which means that Workflow won't complain if the state is autorun and
no or too many activities are present.
The code should be pretty self-explanatory. And, if you have a better
wording instead of "may_stop", we are happy with that too, it's just
what came to mind first.
Thanks again for your work on Workflow, we really appreciate it.
Greetings,
Alex
###
Put here for the reference
Subject: | Workflow_patch_autorun_maystop.diff |
diff -ru Workflow-0.23/lib/Workflow/State.pm ../Workflow-0.23/lib/Workflow/State.pm
--- Workflow-0.23/lib/Workflow/State.pm 2006-09-12 20:15:32.000000000 +0200
+++ ../Workflow-0.23/lib/Workflow/State.pm 2006-12-01 13:05:14.000000000 +0100
@@ -130,6 +130,18 @@
return ( $self->{autorun} eq 'yes' );
}
+sub may_stop {
+ my ( $self, $setting ) = @_;
+ if ( defined $setting ) {
+ if ( $setting =~ /^(true|1|yes)$/i ) {
+ $self->{may_stop} = 'yes';
+ }
+ else {
+ $self->{may_stop} = 'no';
+ }
+ }
+ return ( $self->{may_stop} eq 'yes' );
+}
########################################
# INTERNAL
@@ -152,6 +164,12 @@
else {
$self->autorun( 'no' );
}
+ if ( $config->{may_stop} ) {
+ $self->may_stop( $config->{may_stop} );
+ }
+ else {
+ $self->may_stop( 'no' );
+ }
foreach my $state_action_config ( @{ $config->{action} } ) {
my $action_name = $state_action_config->{name};
my $resulting = $state_action_config->{resulting_state};
@@ -327,6 +345,16 @@
example, you might have two actions with mutually exclusive conditions
within the autorun state.
+If no action or more than one action is available at the time the
+workflow enters an autorun state, Workflow will throw an error. There
+are some conditions where this might not be what you want. For example
+when you have a state which contains an action that depends on some
+condition. If it is true, you might be happy to move on to the next
+state, but if it is not, you are fine to come back and try again later
+if the action is available. This behaviour can be achived by setting the
+'may_stop' property to yes, which will cause Workflow to just quietly
+stop automatic execution if it does not have a single action to execute.
+
=head1 PUBLIC METHODS
=head3 get_conditions( $action_name )
@@ -399,11 +427,16 @@
Returns true if the state should be automatically run, false if
not. To set to true the property value should be 'yes', 'true' or 1.
+=head3 may_stop
+
+Returns true if the state may stop automatic execution silently, false
+if not. To set to true the property value should be 'yes', 'true' or 1.
+
=head1 INTERNAL METHODS
=head3 init( $config )
-Assigns 'state', 'description', and 'autorun' properties from
+Assigns 'state', 'description', 'autorun' and 'may_stop' properties from
C<$config>. Also assigns configuration for all actions in the state,
performing some sanity checks like ensuring every action has a
'resulting_state' key.
diff -ru Workflow-0.23/lib/Workflow.pm ../Workflow-0.23/lib/Workflow.pm
--- Workflow-0.23/lib/Workflow.pm 2006-09-12 20:15:32.000000000 +0200
+++ ../Workflow-0.23/lib/Workflow.pm 2006-12-01 13:05:14.000000000 +0100
@@ -298,11 +298,25 @@
sub _auto_execute_state {
my ( $self, $wf_state ) = @_;
$log ||= get_logger();
- my $action_name = $wf_state->get_autorun_action_name( $self );
- $log->is_debug &&
- $log->debug( "Found action '$action_name' to execute in ",
- "autorun state ", $wf_state->state );
- $self->execute_action( $action_name , 1 );
+ my $action_name;
+ eval {
+ $action_name = $wf_state->get_autorun_action_name( $self );
+ };
+ if ( $@ ) { # we found an error, possibly more than one or none action
+ # are available in this state
+ if ( ! $wf_state->may_stop() ) {
+ # we are in autorun, but stopping is not allowed, so
+ # rethrow
+ my $error = $@;
+ $error->rethrow();
+ }
+ }
+ else { # everything is fine, execute action
+ $log->is_debug &&
+ $log->debug( "Found action '$action_name' to execute in ",
+ "autorun state ", $wf_state->state );
+ $self->execute_action( $action_name , 1 );
+ }
}
1;
@@ -341,8 +355,10 @@
<condition name="can_annotate" />
</action>
</state>
- <state name="annotated">
- <action name="null" resulting_state="finished" />
+ <state name="annotated" autorun="yes" may_stop="yes">
+ <action name="null" resulting_state="finished">
+ <condition name="completed" />
+ </action>
</state>
<state name="finished" />
</workflow>