The concept of "realtime" workflow has been eliminated. Instead all workflows are now realtime (synchronous), and roll over to be asynchronous if they cannot complete succesfully and immediately.
This commit is contained in:
parent
51019e5dca
commit
01d9af6222
15 changed files with 105 additions and 72 deletions
|
|
@ -984,25 +984,12 @@ sub triggerWorkflow {
|
|||
|
||||
my $self = shift;
|
||||
my $workflowId = shift;
|
||||
my $instance = WebGUI::Workflow::Instance->create($self->session, {
|
||||
WebGUI::Workflow::Instance->create($self->session, {
|
||||
workflowId=>$workflowId,
|
||||
className=>"WebGUI::Asset::Wobject::Thingy",
|
||||
methodName=>"new",
|
||||
parameters=>$self->getId
|
||||
});
|
||||
|
||||
# deal with realtime
|
||||
if ($instance->getWorkflow->isRealtime) {
|
||||
my $status = $instance->runAll;
|
||||
if ($status eq "done") {
|
||||
$instance->delete;
|
||||
} else {
|
||||
my $errorMessage = "Realtime workflow instance ".$instance->getId." returned status ".$status." where
|
||||
'done' was expected";
|
||||
$self->session->errorHandler->warn($errorMessage);
|
||||
return $errorMessage;
|
||||
}
|
||||
}
|
||||
})->start;
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ sub _invokeWorkflowOnExportedFiles {
|
|||
my $wfInstance = WebGUI::Workflow::Instance->create($self->session, { workflowId => $self->session->setting->get('trashWorkflow') });
|
||||
$wfInstance->setScratch(WebGUI::Workflow::Activity::DeleteExportedFiles::DELETE_FILES_SCRATCH(), Storable::freeze([defined($lastExportedAs)? ($lastExportedAs) : ()]));
|
||||
$clearExportedAs and $self->session->db->write("UPDATE asset SET lastExportedAs = NULL WHERE assetId = ?", [$self->getId]);
|
||||
$wfInstance->start(1);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ sub createAccountSave {
|
|||
className=>"WebGUI::User",
|
||||
parameters=>$self->session->user->userId,
|
||||
priority=>1
|
||||
});
|
||||
})->start;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ sub login {
|
|||
className=>"WebGUI::User",
|
||||
parameters=>$self->session->user->userId,
|
||||
priority=>3
|
||||
});
|
||||
})->start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,13 +279,13 @@ sub www_runCronJob {
|
|||
if ($taskId) {
|
||||
my $task = WebGUI::Workflow::Cron->new($session, $taskId);
|
||||
return "done" unless (defined $task);
|
||||
my $instance = WebGUI::Workflow::Instance->create($session, {
|
||||
WebGUI::Workflow::Instance->create($session, {
|
||||
workflowId=>$task->get("workflowId"),
|
||||
className=>$task->get("className"),
|
||||
methodName=>$task->get("methodName"),
|
||||
parameters=>$task->get("parameters"),
|
||||
priority=>$task->get("priority"),
|
||||
});
|
||||
})->start(1);
|
||||
$task->delete(1) if ($task->get("runOnce"));
|
||||
return "done";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ sub www_editUserSave {
|
|||
className=>"WebGUI::User",
|
||||
parameters=>$u->userId,
|
||||
priority=>1
|
||||
});
|
||||
})->start;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -532,7 +532,7 @@ sub www_editUserSave {
|
|||
className=>"WebGUI::User",
|
||||
parameters=>$u->userId,
|
||||
priority=>1
|
||||
});
|
||||
})->start;
|
||||
}
|
||||
}
|
||||
# Display an error telling them the username they are trying to use is not available and suggest alternatives
|
||||
|
|
|
|||
|
|
@ -264,7 +264,6 @@ sub www_editWorkflow {
|
|||
singleton=>$i18n->get("singleton"),
|
||||
parallel=>$i18n->get("parallel"),
|
||||
serial=>$i18n->get("serial"),
|
||||
realtime=>$i18n->get("realtime"),
|
||||
},
|
||||
value=>$workflow->get("mode") || "parallel",
|
||||
defaultValue=>"parallel",
|
||||
|
|
|
|||
|
|
@ -400,20 +400,8 @@ sub requestCommit {
|
|||
$self->{_data}{committedBy} = $self->session->user->userId;
|
||||
$self->{_data}{workflowInstanceId} = $instance->getId;
|
||||
$self->session->db->setRow("assetVersionTag","tagId",$self->{_data});
|
||||
|
||||
# deal with realtime
|
||||
if ($instance->getWorkflow->isRealtime) {
|
||||
my $status = $instance->runAll;
|
||||
if ($status eq "done") {
|
||||
$instance->delete;
|
||||
} else {
|
||||
my $errorMessage = "Realtime workflow instance ".$instance->getId." returned status ".$status." where
|
||||
'done' was expected";
|
||||
$self->session->errorHandler->warn($errorMessage);
|
||||
return $errorMessage;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
$instance->start;
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -359,13 +359,12 @@ sub isParallel {
|
|||
|
||||
=head2 isRealtime ( )
|
||||
|
||||
Returns 1 if the mode is set to "realtime".
|
||||
Depricated. Always returns 0.
|
||||
|
||||
=cut
|
||||
|
||||
sub isRealtime {
|
||||
my $self = shift;
|
||||
return ($self->get("mode") eq "realtime") ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ sub execute {
|
|||
className=>$instance->get("className"),
|
||||
parameters=>$instance->get("parameters"),
|
||||
priority=>$instance->get("priority")
|
||||
});
|
||||
})->start(1);
|
||||
$instance->delete;
|
||||
return $self->COMPLETE;
|
||||
} elsif ($instance->getScratch("status") eq "approved") {
|
||||
|
|
|
|||
|
|
@ -58,9 +58,7 @@ The settable properties of the workflow instance. See the set() method for detai
|
|||
=cut
|
||||
|
||||
sub create {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
my $properties = shift;
|
||||
my ($class, $session, $properties, $skipRealtime) = @_;
|
||||
|
||||
# do singleton check
|
||||
my ($isSingleton) = $session->db->quickArray("select count(*) from Workflow where workflowId=? and
|
||||
|
|
@ -74,9 +72,8 @@ sub create {
|
|||
# create instance
|
||||
my $instanceId = $session->db->setRow("WorkflowInstance","instanceId",{instanceId=>"new", runningSince=>time()});
|
||||
my $self = $class->new($session, $instanceId);
|
||||
$properties->{notifySpectre} = 1 unless ($properties->{notifySpectre} eq "0");
|
||||
$properties->{newlyCreated} = 1;
|
||||
$self->set($properties);
|
||||
$self->set($properties,1);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
|
@ -130,6 +127,10 @@ Deconstructor.
|
|||
|
||||
sub DESTROY {
|
||||
my $self = shift;
|
||||
# start the workflow in case the programmer forgot
|
||||
unless ($self->{_started}) {
|
||||
$self->start;
|
||||
}
|
||||
delete $self->{_workflow};
|
||||
undef $self;
|
||||
}
|
||||
|
|
@ -268,7 +269,7 @@ sub new {
|
|||
my $instanceId = shift;
|
||||
my $data = $session->db->getRow("WorkflowInstance","instanceId", $instanceId);
|
||||
return undef unless $data->{instanceId};
|
||||
bless {_session=>$session, _id=>$instanceId, _data=>$data}, $class;
|
||||
bless {_session=>$session, _id=>$instanceId, _data=>$data, _started=>0}, $class;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -290,11 +291,11 @@ sub run {
|
|||
my $self = shift;
|
||||
my $workflow = $self->getWorkflow;
|
||||
unless (defined $workflow) {
|
||||
$self->set({lastStatus=>"undefined", notifySpectre=>0});
|
||||
$self->set({lastStatus=>"undefined"}, 1);
|
||||
return "undefined";
|
||||
}
|
||||
unless ($workflow->get("enabled")) {
|
||||
$self->set({lastStatus=>"disabled", notifySpectre=>0});
|
||||
$self->set({lastStatus=>"disabled"}, 1);
|
||||
return "disabled";
|
||||
}
|
||||
if ($workflow->isSerial) {
|
||||
|
|
@ -303,7 +304,7 @@ sub run {
|
|||
[$workflow->getId]
|
||||
);
|
||||
if ($self->getId ne $firstId) { # must wait for currently running instance to complete
|
||||
$self->set({lastStatus=>"waiting", notifySpectre=>0});
|
||||
$self->set({lastStatus=>"waiting"}, 1);
|
||||
return "waiting";
|
||||
}
|
||||
}
|
||||
|
|
@ -322,21 +323,21 @@ sub run {
|
|||
$object = eval { WebGUI::Pluggable::instanciate($class, $method, [$self->session, $params]) };
|
||||
if ($@) {
|
||||
$self->session->errorHandler->error($@);
|
||||
$self->set({lastStatus=>"error", notifySpectre=>0});
|
||||
$self->set({lastStatus=>"error"}, 1);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
$status = eval { $activity->execute($object, $self) };
|
||||
if ($@) {
|
||||
$self->session->errorHandler->error("Caught exception executing workflow activity ".$activity->getId." for instance ".$self->getId." which reported ".$@);
|
||||
$self->set({lastStatus=>"error", notifySpectre=>0});
|
||||
$self->set({lastStatus=>"error"}, 1);
|
||||
return "error";
|
||||
}
|
||||
if ($status eq "complete") {
|
||||
$self->set({lastStatus=>"complete", "currentActivityId"=>$activity->getId, notifySpectre=>0});
|
||||
$self->set({lastStatus=>"complete", "currentActivityId"=>$activity->getId}, 1);
|
||||
}
|
||||
else {
|
||||
$self->set({lastStatus=>$status, notifySpectre=>0});
|
||||
$self->set({lastStatus=>$status}, 1);
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
|
@ -345,7 +346,7 @@ sub run {
|
|||
|
||||
=head2 runAll ( )
|
||||
|
||||
Runs all activities in this workflow instance, and returns the last status code, which should be "done" unless
|
||||
Depricated. Runs all activities in this workflow instance, and returns the last status code, which should be "done" unless
|
||||
something bad happens.
|
||||
|
||||
=cut
|
||||
|
|
@ -374,7 +375,7 @@ sub session {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 set ( properties )
|
||||
=head2 set ( properties, [ skipSpectreNotification ])
|
||||
|
||||
Sets one or more of the properties of this workflow instance.
|
||||
|
||||
|
|
@ -410,11 +411,14 @@ The unique id of the activity in the workflow that needs to be executed next. If
|
|||
|
||||
See the run() method for a description of statuses.
|
||||
|
||||
=head3 skipSpectreNotification
|
||||
|
||||
A boolean, that if set to 1 will not inform Spectre of the change in settings.
|
||||
|
||||
=cut
|
||||
|
||||
sub set {
|
||||
my $self = shift;
|
||||
my $properties = shift;
|
||||
my ($self, $properties, $skipNotify) = @_;
|
||||
$self->{_data}{priority} = $properties->{priority} || $self->{_data}{priority} || 2;
|
||||
$self->{_data}{lastStatus} = $properties->{lastStatus} || $self->{_data}{lastStatus};
|
||||
$self->{_data}{workflowId} = $properties->{workflowId} || $self->{_data}{workflowId};
|
||||
|
|
@ -426,9 +430,9 @@ sub set {
|
|||
$self->{_data}{currentActivityId} = (exists $properties->{currentActivityId}) ? $properties->{currentActivityId} : $self->{_data}{currentActivityId};
|
||||
$self->{_data}{lastUpdate} = time();
|
||||
$self->session->db->setRow("WorkflowInstance","instanceId",$self->{_data});
|
||||
if (!$self->getWorkflow->isRealtime && $properties->{notifySpectre}) {
|
||||
unless ($skipNotify) {
|
||||
my $spectre = WebGUI::Workflow::Spectre->new($self->session);
|
||||
$spectre->notify("workflow/deleteInstance",$self->getId) unless ($properties->{newlyCreated});
|
||||
$spectre->notify("workflow/deleteInstance",$self->getId);
|
||||
$spectre->notify("workflow/addInstance", {cookieName=>$self->session->config->getCookieName, gateway=>$self->session->config->get("gateway"), sitename=>$self->session->config->get("sitename")->[0], instanceId=>$self->getId, priority=>$self->{_data}{priority}});
|
||||
}
|
||||
}
|
||||
|
|
@ -458,6 +462,47 @@ sub setScratch {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 start ( [ skipRealtime ] )
|
||||
|
||||
Tells the workflow instance that it's ok to start executing.
|
||||
|
||||
=head3 skipRealtime
|
||||
|
||||
When a workflow instance is started WebGUI tries to run it immediately to see if it can be completely executed in realtime. However, if you'd like to skip this option set this boolean to 1.
|
||||
|
||||
=cut
|
||||
|
||||
sub start {
|
||||
my ($self, $skipRealtime) = @_;
|
||||
my $log = $self->session->errorHandler;
|
||||
$self->{_started} = 1;
|
||||
|
||||
# run the workflow in realtime to start.
|
||||
unless ($skipRealtime) {
|
||||
my $start = time();
|
||||
my $status = "complete";
|
||||
$log->info('Trying to execute workflow instance '.$self->getId.' in realtime.');
|
||||
while ($status eq "complete" && ($start > time() -10)) { # how much can we run in 10 seconds
|
||||
$status = $self->run;
|
||||
$log->info('Completed activity for workflow instance '.$self->getId.' in realtime with return status of '.$status.'.');
|
||||
}
|
||||
|
||||
# we were able to complete the workflow in realtime
|
||||
if ($status eq "done") {
|
||||
$log->info('Completed workflow instance '.$self->getId.' in realtime.');
|
||||
$self->delete;
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
# hand off the workflow to spectre
|
||||
$log->info('Could not complete workflow instance '.$self->getId.' in realtime, handing off to Spectre.');
|
||||
my $spectre = WebGUI::Workflow::Spectre->new($self->session);
|
||||
$spectre->notify("workflow/addInstance", {cookieName=>$self->session->config->getCookieName, gateway=>$self->session->config->get("gateway"), sitename=>$self->session->config->get("sitename")->[0], instanceId=>$self->getId, priority=>$self->{_data}{priority}});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,24 +62,17 @@ our $I18N = {
|
|||
message => q|Parallel|,
|
||||
},
|
||||
|
||||
'realtime' => {
|
||||
message => q|Realtime|,
|
||||
},
|
||||
|
||||
'mode' => {
|
||||
message => q|Mode|,
|
||||
},
|
||||
|
||||
'mode help' => {
|
||||
message => q|The mode of a workflow determines the precidence of when and how a workflow is run.
|
||||
<p><b>Parallel</b> workflows asynchronously run as many instances of the workflow as there are in existence.</p>
|
||||
<p><b>Singleton</b> workflows asynchronously run exactly one instance of a given type at any one time, and if a
|
||||
message => q|The mode of a workflow determines when and how a workflow is run.
|
||||
<p><b>Parallel</b> workflows run as many instances of the workflow as there are in existence.</p>
|
||||
<p><b>Singleton</b> workflows run exactly one instance of a given type at any one time, and if a
|
||||
new workflow of that type is created while the original is running, it will be discarded.</p>
|
||||
<p><b>Serial</b> workflows asynchronously run one workflow instance of a given type at a time, in the order it was
|
||||
created.</p>
|
||||
<p><b>Realtime</b> workflows synchronously (immediately) run all activities associated with it, because of this
|
||||
not all triggers support realtime workflows, and you can't use any asynchronous workflow activities (like
|
||||
version tag approval) in realtime workflows.</p>|,
|
||||
<p><b>Serial</b> workflows run one workflow instance of a given type at a time, in the order it was
|
||||
created.</p> |,
|
||||
context => q|the hover help for the mode field|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue