diff --git a/docs/upgrades/upgrade_6.8.8-6.99.0.pl b/docs/upgrades/upgrade_6.8.8-6.99.0.pl
index 1773d7be0..84a483d13 100644
--- a/docs/upgrades/upgrade_6.8.8-6.99.0.pl
+++ b/docs/upgrades/upgrade_6.8.8-6.99.0.pl
@@ -351,7 +351,8 @@ sub addWorkflow {
methodName varchar(255),
parameters text,
runningSince bigint,
- lastUpdate bigint
+ lastUpdate bigint,
+ lastStatus varchar(15)
)");
$session->db->write("create table WorkflowInstanceScratch (
instanceId varchar(22) binary not null,
diff --git a/lib/WebGUI/Operation.pm b/lib/WebGUI/Operation.pm
index bbb41de2d..ea793bca1 100644
--- a/lib/WebGUI/Operation.pm
+++ b/lib/WebGUI/Operation.pm
@@ -282,6 +282,7 @@ sub getOperations {
'manageWorkflows' => 'WebGUI::Operation::Workflow',
'promoteWorkflowActivity' => 'WebGUI::Operation::Workflow',
'runWorkflow' => 'WebGUI::Operation::Workflow',
+ 'showRunningWorkflows' => 'WebGUI::Operation::Workflow',
};
}
diff --git a/lib/WebGUI/Operation/Workflow.pm b/lib/WebGUI/Operation/Workflow.pm
index 8f7701635..be53e2cf7 100644
--- a/lib/WebGUI/Operation/Workflow.pm
+++ b/lib/WebGUI/Operation/Workflow.pm
@@ -330,6 +330,7 @@ sub www_manageWorkflows {
$output .= '';
my $ac = WebGUI::AdminConsole->new($session,"workflow");
$ac->addSubmenuItem($session->url->page("op=addWorkflow"), $i18n->get("add a new workflow"));
+ $ac->addSubmenuItem($session->url->page("op=showRunningWorkflows"), $i18n->get("show running workflows"));
return $ac->render($output);
}
@@ -382,4 +383,45 @@ sub www_runWorkflow {
return "error";
}
+#-------------------------------------------------------------------
+
+=head2 www_showRunningWorkflows ( )
+
+Display a list of the running workflow instances.
+
+=cut
+
+sub www_showRunningWorkflows {
+ my $session = shift;
+ return $session->privilege->insufficient() unless ($session->user->isInGroup("pbgroup000000000000015"));
+ my $i18n = WebGUI::International->new($session, "Workflow");
+ my $output = '
';
+ my $rs = $session->db->read("select Workflow.title, WorkflowInstance.lastStatus, WorkflowInstance.runningSince, WorkflowInstance.lastUpdate from WorkflowInstance left join Workflow on WorkflowInstance.workflowId=Workflow.workflowId order by WorkflowInstance.runningSince desc");
+ while (my ($title, $status, $runningSince, $lastUpdate) = $rs->array) {
+ my $class = $status || "complete";
+ $output .= ''
+ .'| '.$title.' | '
+ .''.$session->datetime->epochToHuman($runningSince).' | ';
+ if ($status) {
+ $output .= ''
+ .$status.' / '.$session->datetime->epochToHuman($lastUpdate)
+ .' | ';
+ }
+ $output .= "
\n";
+ }
+ $output .= '
';
+ my $ac = WebGUI::AdminConsole->new($session,"workflow");
+ $ac->addSubmenuItem($session->url->page("op=addWorkflow"), $i18n->get("add a new workflow"));
+ $ac->addSubmenuItem($session->url->page("op=manageWorkflows"), $i18n->get("manage workflows"));
+ return $ac->render($output);
+}
+
+
1;
diff --git a/lib/WebGUI/Workflow/Instance.pm b/lib/WebGUI/Workflow/Instance.pm
index d257dafcd..418fbdbfe 100644
--- a/lib/WebGUI/Workflow/Instance.pm
+++ b/lib/WebGUI/Workflow/Instance.pm
@@ -237,11 +237,20 @@ Executes the next iteration in this workflow. Returns a status code based upon w
sub run {
my $self = shift;
my $workflow = $self->getWorkflow;
- return "undefined" unless (defined $workflow);
- return "disabled" unless ($workflow->get("enabled"));
+ unless (defined $workflow) {
+ $self->set({lastStatus=>"undefined", notifySpectre=>0});
+ return "undefined";
+ }
+ unless ($workflow->get("enabled")) {
+ $self->set({lastStatus=>"disabled", notifySpectre=>0});
+ return "disabled";
+ }
if ($workflow->get("isSerial")) {
my ($firstId) = $self->session->db->quickArray("select workflowId from WorkflowInstance order by runningSince");
- return "waiting" if ($workflow->getId ne $firstId); # must wait for currently running instance to complete
+ if ($workflow->getId ne $firstId) { # must wait for currently running instance to complete
+ $self->set({lastStatus=>"waiting", notifySpectre=>0});
+ return "waiting";
+ }
}
my $activity = $workflow->getNextActivity($self->get("currentActivityId"));
unless (defined $activity) {
@@ -258,31 +267,38 @@ sub run {
eval($cmd);
if ($@) {
$self->session->errorHandler->error("Error loading activity class $class: ".$@);
+ $self->set({lastStatus=>"error", notifySpectre=>0});
return "error";
}
my $object = eval{ $class->$method($self->session, $params) };
if ($@) {
$self->session->errorHandler->error("Error instanciating activity (".$activity->getId.") pass-in object: ".$@);
+ $self->set({lastStatus=>"error", notifySpectre=>0});
return "error";
}
unless (defined $object) {
$self->session->errorHandler->error("Pass in object came back undefined for activity (".$activity->getId.") using ".$class.", ".$method.", ".$params.".");
+ $self->set({lastStatus=>"error", notifySpectre=>0});
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});
return "error";
}
} else {
$status = $activity->execute(undef, $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});
return "error";
}
}
if ($status eq "complete") {
- $self->set({"currentActivityId"=>$activity->getId, notifySpectre=>0});
+ $self->set({lastStatus=>"complete", "currentActivityId"=>$activity->getId, notifySpectre=>0});
+ } else {
+ $self->set({lastStatus=>"error", notifySpectre=>0});
}
return $status;
}
@@ -335,12 +351,17 @@ The parameters to be passed into the constructor. Note that the system will alwa
The unique id of the activity in the workflow that needs to be executed next. If blank, it will execute the first activity in the workflow.
+=head4 lastStatus
+
+See the run() method for a description of statuses.
+
=cut
sub set {
my $self = shift;
my $properties = shift;
$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};
$self->{_data}{className} = (exists $properties->{className}) ? $properties->{className} : $self->{_data}{className};
$self->{_data}{methodName} = (exists $properties->{methodName}) ? $properties->{methodName} : $self->{_data}{methodName};
diff --git a/lib/WebGUI/i18n/English/Workflow.pm b/lib/WebGUI/i18n/English/Workflow.pm
index 49f32ea25..5061f50f3 100644
--- a/lib/WebGUI/i18n/English/Workflow.pm
+++ b/lib/WebGUI/i18n/English/Workflow.pm
@@ -1,6 +1,12 @@
package WebGUI::i18n::English::Workflow;
our $I18N = {
+ 'show running workflows' => {
+ message => q|Show running workflows.|,
+ context => q|A label used to get to a display of running workflows.|,
+ lastUpdated => 0,
+ },
+
'no object' => {
message => q|No Object|,
context => q|used when selecting an object type to be passed through a workflow|,