spectre/workflows/priorities RFE
This commit is contained in:
parent
794da40e5c
commit
60eeebdba9
10 changed files with 556 additions and 51 deletions
|
|
@ -19,6 +19,7 @@ use DateTime;
|
|||
use HTTP::Request::Common;
|
||||
use HTTP::Cookies;
|
||||
use POE qw(Component::Client::HTTP);
|
||||
use JSON 'objToJson';
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -29,12 +30,12 @@ Initializes the scheduler.
|
|||
=cut
|
||||
|
||||
sub _start {
|
||||
my ($kernel, $self, $publicEvents) = @_[ KERNEL, OBJECT, ARG0 ];
|
||||
$self->debug("Starting Spectre scheduler.");
|
||||
my $serviceName = "cron";
|
||||
$kernel->alias_set($serviceName);
|
||||
$kernel->call( IKC => publish => $serviceName, $publicEvents );
|
||||
$kernel->yield("checkSchedules");
|
||||
my ($kernel, $self, $publicEvents) = @_[ KERNEL, OBJECT, ARG0 ];
|
||||
$self->debug("Starting Spectre scheduler.");
|
||||
my $serviceName = "cron";
|
||||
$kernel->alias_set($serviceName);
|
||||
$kernel->call( IKC => publish => $serviceName, $publicEvents );
|
||||
$kernel->yield("checkSchedules");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -46,9 +47,9 @@ Gracefully shuts down the scheduler.
|
|||
=cut
|
||||
|
||||
sub _stop {
|
||||
my ($kernel, $self) = @_[KERNEL, OBJECT];
|
||||
$self->debug("Stopping the scheduler.");
|
||||
undef $self;
|
||||
my ($kernel, $self) = @_[KERNEL, OBJECT];
|
||||
$self->debug("Stopping the scheduler.");
|
||||
undef $self;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -318,7 +319,27 @@ sub getJob {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head3 getLogger ( )
|
||||
=head2 getJsonStatus ( )
|
||||
|
||||
Returns JSON of the jobs.
|
||||
|
||||
=cut
|
||||
|
||||
sub getJsonStatus {
|
||||
my ($kernel, $request, $self) = @_[KERNEL,ARG0,OBJECT];
|
||||
my ($sitename, $rsvp) = @$request;
|
||||
my %data = ();
|
||||
for my $key (keys %{ $self->{_jobs} }) {
|
||||
next unless $self->{_jobs}->{$key}->{sitename} eq $sitename;
|
||||
$data{$key} = $self->{_jobs}->{$key};
|
||||
}
|
||||
$kernel->call(IKC => post => $rsvp, objToJson(\%data));
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getLogger ( )
|
||||
|
||||
Returns a reference to the logger.
|
||||
|
||||
|
|
@ -357,7 +378,7 @@ sub new {
|
|||
my $debug = shift;
|
||||
my $self = {_jobs=>{}, _debug=>$debug, _config=>$config, _logger=>$logger};
|
||||
bless $self, $class;
|
||||
my @publicEvents = qw(runJob runJobResponse addJob deleteJob);
|
||||
my @publicEvents = qw(runJob runJobResponse addJob deleteJob getJsonStatus);
|
||||
POE::Session->create(
|
||||
object_states => [ $self => [qw(_start _stop runJob runJobResponse addJob deleteJob checkSchedules checkSchedule), @publicEvents] ],
|
||||
args=>[\@publicEvents]
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use HTTP::Cookies;
|
|||
use POE qw(Component::Client::HTTP);
|
||||
use POE::Queue::Array;
|
||||
use Tie::IxHash;
|
||||
use JSON 'objToJson';
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -177,6 +178,66 @@ sub deleteInstance {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 editWorkflowPriority ( href )
|
||||
|
||||
Updates the priority of a given workflow instance.
|
||||
|
||||
=head3 href
|
||||
|
||||
Contains information about the instance and the new priority.
|
||||
|
||||
=head4 instanceId
|
||||
|
||||
The id of the instance to update.
|
||||
|
||||
=head4 newPriority
|
||||
|
||||
The new priority value.
|
||||
|
||||
=cut
|
||||
|
||||
sub editWorkflowPriority {
|
||||
my ($self, $request, $kernel, $session ) = @_[OBJECT, ARG0, KERNEL, SESSION];
|
||||
my ($argsHref, $rsvp) = @$request;
|
||||
|
||||
my $instanceId = $argsHref->{instanceId};
|
||||
my $newPriority = $argsHref->{newPriority};
|
||||
|
||||
$self->debug("Updating the priority of $instanceId to $newPriority.");
|
||||
|
||||
# I'm guessing that the payload can't change queues on us
|
||||
my $found = 0;
|
||||
my $filterCref = sub { shift->{instanceId} eq $instanceId };
|
||||
for my $getQueueMethod (map "get${_}Queue", qw( Suspended Waiting Running )) {
|
||||
my $q = $self->$getQueueMethod;
|
||||
my($itemAref) = $q->peek_items($filterCref); # there should be only one
|
||||
|
||||
next unless (ref $itemAref eq 'ARRAY' and @$itemAref);
|
||||
|
||||
my($priority, $id, $payload) = @$itemAref;
|
||||
my $ackPriority = $q->set_priority($id, $filterCref, $newPriority);
|
||||
if ($ackPriority != $newPriority) {
|
||||
# return an error
|
||||
my $error = 'edit priority setting error';
|
||||
$kernel->call(IKC=>post=>$rsvp, objToJson({message => $error}));
|
||||
}
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
|
||||
if (! $found) {
|
||||
# return an error message
|
||||
my $error = 'edit priority instance not found error';
|
||||
$kernel->call(IKC=>post=>$rsvp, objToJson({message => $error}));
|
||||
}
|
||||
else {
|
||||
# return success message
|
||||
$kernel->call(IKC=>post=>$rsvp, objToJson({message => 'edit priority success'}));
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 error ( output )
|
||||
|
||||
Prints out error information if debug is enabled.
|
||||
|
|
@ -198,6 +259,44 @@ sub error {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getJsonStatus ( )
|
||||
|
||||
Returns JSON report about the workflow engine.
|
||||
|
||||
=cut
|
||||
|
||||
sub getJsonStatus {
|
||||
my ($kernel, $request, $self) = @_[KERNEL,ARG0,OBJECT];
|
||||
my ($sitename, $rsvp) = @$request;
|
||||
|
||||
# only return this site's info
|
||||
return $kernel->call(IKC=>post=>$rsvp, '{}') unless $sitename;
|
||||
|
||||
my %queues = ();
|
||||
tie %queues, 'Tie::IxHash';
|
||||
%queues = (
|
||||
Suspended => $self->getSuspendedQueue,
|
||||
Waiting => $self->getWaitingQueue,
|
||||
Running => $self->getRunningQueue,
|
||||
);
|
||||
my %output = ();
|
||||
foreach my $queueName (keys %queues) {
|
||||
my $queue = $queues{$queueName};
|
||||
my $count = $queue->get_item_count;
|
||||
my @instances;
|
||||
if ($count > 0) {
|
||||
foreach my $itemAref ($queue->peek_items(sub { shift()->{sitename} eq $sitename })) {
|
||||
push @instances, $itemAref;
|
||||
}
|
||||
}
|
||||
$output{$queueName} = \@instances;
|
||||
}
|
||||
|
||||
$kernel->call(IKC=>post=>$rsvp, objToJson(\%output));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getLogger ( )
|
||||
|
||||
Returns a reference to the logger.
|
||||
|
|
@ -340,7 +439,7 @@ sub new {
|
|||
my $debug = shift;
|
||||
my $self = {_debug=>$debug, _config=>$config, _logger=>$logger};
|
||||
bless $self, $class;
|
||||
my @publicEvents = qw(addInstance deleteInstance getStatus);
|
||||
my @publicEvents = qw(addInstance deleteInstance editWorkflowPriority getStatus getJsonStatus);
|
||||
POE::Session->create(
|
||||
object_states => [ $self => [qw(_start _stop returnInstanceToRunnableState addInstance checkInstances deleteInstance suspendInstance runWorker workerResponse), @publicEvents] ],
|
||||
args=>[\@publicEvents]
|
||||
|
|
@ -431,10 +530,11 @@ Suspends a workflow instance for a number of seconds defined in the config file,
|
|||
=cut
|
||||
|
||||
sub suspendInstance {
|
||||
my ($self, $instance, $kernel) = @_[OBJECT, ARG0, KERNEL];
|
||||
$self->debug("Suspending workflow instance ".$instance->{instanceId}." for ".$self->config->get("suspensionDelay")." seconds.");
|
||||
$self->getSuspendedQueue->enqueue("1", $instance);
|
||||
$kernel->delay_set("returnInstanceToRunnableState",$self->config->get("suspensionDelay"), $instance);
|
||||
my ($self, $instance, $kernel) = @_[OBJECT, ARG0, KERNEL];
|
||||
$self->debug("Suspending workflow instance ".$instance->{instanceId}." for ".$self->config->get("suspensionDelay")." seconds.");
|
||||
my $priority = ($instance->{priority} - 1) * 10;
|
||||
$self->getSuspendedQueue->enqueue($priority, $instance);
|
||||
$kernel->delay_set("returnInstanceToRunnableState",$self->config->get("suspensionDelay"), $instance);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -182,6 +182,15 @@ sub getAdminFunction {
|
|||
my $self = shift;
|
||||
my $id = shift;
|
||||
my $functions = { # at some point in the future we'll need to make this pluggable/configurable
|
||||
"spectre"=>{
|
||||
title=>{
|
||||
id=>"spectre",
|
||||
namespace=>"Spectre"
|
||||
},
|
||||
icon=>"spectre.gif",
|
||||
op=>"spectreStatus",
|
||||
group=>"3"
|
||||
},
|
||||
"assets"=>{
|
||||
title=>{
|
||||
id=>"assets",
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ sub getOperations {
|
|||
|
||||
'spectreGetSiteData' => 'WebGUI::Operation::Spectre',
|
||||
'spectreTest' => 'WebGUI::Operation::Spectre',
|
||||
'spectreStatus' => 'WebGUI::Operation::Spectre',
|
||||
|
||||
'ssoViaSessionId' => 'WebGUI::Operation::SSO',
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,70 @@ sub www_spectreGetSiteData {
|
|||
return JSON::objToJson(\%siteData,{autoconv=>0, skipinvalid=>1});
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_spectreStatus ( )
|
||||
|
||||
Show information about Spectre's current workload.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_spectreStatus {
|
||||
my $session = shift;
|
||||
|
||||
return $session->privilege->adminOnly() unless $session->user->isInGroup(3);
|
||||
|
||||
# start to prepare the display
|
||||
my $ac = WebGUI::AdminConsole->new($session, 'spectre');
|
||||
my $i18n = WebGUI::International->new($session, 'Spectre');
|
||||
|
||||
$session->http->setCacheControl("none");
|
||||
unless (isInSubnet($session->env->get("REMOTE_ADDR"), $session->config->get("spectreSubnets"))) {
|
||||
$session->errorHandler->security("make a Spectre workflow runner request, but we're only allowed to accept requests from ".join(",",@{$session->config->get("spectreSubnets")}).".");
|
||||
return "subnet";
|
||||
}
|
||||
|
||||
my $remote = create_ikc_client(
|
||||
port=>$session->config->get("spectrePort"),
|
||||
ip=>$session->config->get("spectreIp"),
|
||||
name=>rand(100000),
|
||||
timeout=>10
|
||||
);
|
||||
|
||||
if (!$remote) {
|
||||
return $ac->render($i18n->get('not running'), $i18n->get('spectre'));
|
||||
}
|
||||
|
||||
my $sitename = $session->config()->get('sitename')->[0];
|
||||
my $workflowResult = $remote->post_respond('workflow/getJsonStatus',$sitename);
|
||||
if (!$workflowResult) {
|
||||
$remote->disconnect();
|
||||
return $ac->render($i18n->get('workflow status error'), $i18n->get('spectre'));
|
||||
}
|
||||
|
||||
my $cronResult = $remote->post_respond('cron/getJsonStatus',$sitename);
|
||||
if (! defined $cronResult) {
|
||||
$remote->disconnect();
|
||||
return $ac->render($i18n->get('cron status error'), $i18n->get('spectre'));
|
||||
}
|
||||
|
||||
my %data = (
|
||||
workflow => jsonToObj($workflowResult),
|
||||
cron => jsonToObj($cronResult),
|
||||
);
|
||||
|
||||
my $workflowCount = @{ $data{workflow}{Suspended} } + @{ $data{workflow}{Waiting} } + @{ $data{workflow}{Running} };
|
||||
my $workflowUrl = $session->url->page('op=showRunningWorkflows');
|
||||
my $cronCount = keys %{ $data{cron} };
|
||||
my $cronUrl = $session->url->page('op=manageCron');
|
||||
|
||||
my $output = $i18n->get('running').'<br/>';
|
||||
$output .= sprintf $i18n->get('workflow header'), $workflowUrl, $workflowCount;
|
||||
$output .= sprintf $i18n->get('cron header'), $cronUrl, $cronCount;
|
||||
|
||||
return $ac->render($output, $i18n->get('spectre'));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_spectreTest ( )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ use WebGUI::Workflow;
|
|||
use WebGUI::Workflow::Activity;
|
||||
use WebGUI::Workflow::Instance;
|
||||
use WebGUI::Utility;
|
||||
use POE::Component::IKC::ClientLite;
|
||||
use JSON 'jsonToObj';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -231,6 +233,60 @@ sub www_editWorkflow {
|
|||
return $ac->render($f->print.$addmenu.$steps, 'edit workflow');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_editWorkflowPriority ( )
|
||||
|
||||
Save the submitted new workflow priority.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_editWorkflowPriority {
|
||||
my $session = shift;
|
||||
|
||||
return $session->privilege->insufficient() unless $session->user->isInGroup(3);
|
||||
|
||||
my $i18n = WebGUI::International->new($session, 'Workflow');
|
||||
my $ac = WebGUI::AdminConsole->new($session,"workflow");
|
||||
$ac->addSubmenuItem($session->url->page("op=showRunningWorkflows"), $i18n->get('show running workflows'));
|
||||
$ac->setHelp('manage workflows', 'Workflow');
|
||||
|
||||
# make sure the input is good
|
||||
my $instanceId = $session->form->get('instanceId') || '';
|
||||
my $newPriority = $session->form->get('newPriority') || '';
|
||||
if (! $instanceId) {
|
||||
my $output = $i18n->get('edit priority bad request');
|
||||
return $ac->render($output, $i18n->get('show running workflows'));
|
||||
}
|
||||
|
||||
# make the request
|
||||
my $remote = create_ikc_client(
|
||||
port=>$session->config->get("spectrePort"),
|
||||
ip=>$session->config->get("spectreIp"),
|
||||
name=>rand(100000),
|
||||
timeout=>10
|
||||
);
|
||||
if (! $remote) {
|
||||
my $output = $i18n->get('edit priority no spectre error');
|
||||
return $ac->render($output, $i18n->get('show running workflows'));
|
||||
}
|
||||
|
||||
my $argHref = {
|
||||
instanceId => $instanceId,
|
||||
newPriority => $newPriority,
|
||||
};
|
||||
my $resultJson = $remote->post_respond('workflow/editWorkflowPriority', $argHref);
|
||||
if (! defined $resultJson) {
|
||||
$remote->disconnect();
|
||||
my $output = $i18n->get('edit priority no info error');
|
||||
return $ac->render($output, $i18n->get('show running workflows'));
|
||||
}
|
||||
|
||||
my $responseHref = jsonToObj($resultJson);
|
||||
|
||||
my $message = $i18n->get($responseHref->{message}) || $i18n->get('edit priority unknown error');
|
||||
return $ac->render($message, $i18n->get('show running workflows'));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -397,39 +453,132 @@ 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 = '<style>
|
||||
.waiting { color: #808000; }
|
||||
.complete { color: #008000; }
|
||||
.error { color: #800000; }
|
||||
.disabled { color: #808000; }
|
||||
.done { color: #008000; }
|
||||
.undefined { color: #800000; }
|
||||
</style><table style="width: 100%;">';
|
||||
my $isAdmin = $session->user->isInGroup("3");
|
||||
my $rs = $session->db->read("select Workflow.title, WorkflowInstance.lastStatus, WorkflowInstance.runningSince, WorkflowInstance.lastUpdate, WorkflowInstance.instanceId from WorkflowInstance left join Workflow on WorkflowInstance.workflowId=Workflow.workflowId order by WorkflowInstance.runningSince desc");
|
||||
while (my ($title, $status, $runningSince, $lastUpdate, $id) = $rs->array) {
|
||||
my $class = $status || "complete";
|
||||
$output .= '<tr class="'.$class.'">'
|
||||
.'<td>'.$title.'</td>'
|
||||
.'<td>'.$session->datetime->epochToHuman($runningSince).'</td>';
|
||||
if ($status) {
|
||||
$output .= '<td>'
|
||||
.$status.' / '.$session->datetime->epochToHuman($lastUpdate)
|
||||
.'</td>';
|
||||
}
|
||||
$output .= '<td><a href="'.$session->url->page("op=runWorkflow;instanceId=".$id).'">'.$i18n->get("run").'</a></td>' if ($isAdmin);
|
||||
$output .= "</tr>\n";
|
||||
}
|
||||
$output .= '</table>';
|
||||
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"));
|
||||
$ac->setHelp('show running workflows', 'Workflow');
|
||||
return $ac->render($output, 'show running workflows');
|
||||
my $session = shift;
|
||||
|
||||
return $session->privilege->insufficient() unless ($session->user->isInGroup("pbgroup000000000000015"));
|
||||
|
||||
my $i18n = WebGUI::International->new($session, "Workflow");
|
||||
my $ac = WebGUI::AdminConsole->new($session,"workflow");
|
||||
my $isAdmin = $session->user->isInGroup("3");
|
||||
|
||||
# javascript for creating/showing/hiding the edit priority form
|
||||
my $cancel = $i18n->get('edit priority cancel');
|
||||
my $updatePriority = $i18n->get('edit priority update priority');
|
||||
my $output = <<"ENDCODE";
|
||||
<style>
|
||||
.waiting { color: #808000; }
|
||||
.complete { color: #008000; }
|
||||
.error { color: #800000; }
|
||||
.disabled { color: #808000; }
|
||||
.done { color: #008000; }
|
||||
.undefined { color: #800000; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function showEditPriorityForm(iid) {
|
||||
var alreadyOpenForm = document.getElementById('edit-priority-form');
|
||||
if (alreadyOpenForm) {
|
||||
var oldIid = alreadyOpenForm.instanceId.value;
|
||||
hideEditPriorityForm(oldIid);
|
||||
}
|
||||
var ele = document.getElementById('priority-'+iid)
|
||||
ele.style.display = 'none';
|
||||
ele.parentNode.insertBefore(getEditPriorityFormNode(iid,ele.innerHTML),ele);
|
||||
}
|
||||
function getEditPriorityFormNode(iid,currentPriority) {
|
||||
var f = document.createElement('form');
|
||||
f.setAttribute('id','edit-priority-form');
|
||||
f.setAttribute('method','POST');
|
||||
f.setAttribute('action','?op=editWorkflowPriority');
|
||||
f.innerHTML = '<input type="hidden" name="instanceId" value="'+iid+'"/>'+
|
||||
'<input type="input" name="newPriority" size="3" value="'+currentPriority+'"/>'+
|
||||
'<input type="submit" value="$updatePriority"/>'+
|
||||
'<a href="javascript:void(0)" onclick="hideEditPriorityForm(\\''+iid+'\\')">$cancel</a>';
|
||||
return f;
|
||||
}
|
||||
function hideEditPriorityForm(iid) {
|
||||
var f = document.getElementById('edit-priority-form');
|
||||
f.parentNode.removeChild(f);
|
||||
document.getElementById('priority-'+iid).style.display = '';
|
||||
}
|
||||
</script>
|
||||
ENDCODE
|
||||
|
||||
my $remote = create_ikc_client(
|
||||
port=>$session->config->get("spectrePort"),
|
||||
ip=>$session->config->get("spectreIp"),
|
||||
name=>rand(100000),
|
||||
timeout=>10
|
||||
);
|
||||
if (! $remote) {
|
||||
my $output = $i18n->get('spectre not running error');
|
||||
return $ac->render($output, $i18n->get('show running workflows'));
|
||||
}
|
||||
|
||||
my $sitename = $session->config()->get('sitename')->[0];
|
||||
my $workflowResult = $remote->post_respond('workflow/getJsonStatus',$sitename);
|
||||
if (! defined $workflowResult) {
|
||||
$remote->disconnect();
|
||||
my $output = $i18n->get('spectre no info error');
|
||||
return $ac->render($output, $i18n->get('show running workflows'));
|
||||
}
|
||||
|
||||
my $workflowsHref = jsonToObj($workflowResult);
|
||||
|
||||
my $workflowTitleFor = $session->db->buildHashRef(<<"");
|
||||
SELECT wi.instanceId, w.title
|
||||
FROM WorkflowInstance wi
|
||||
JOIN Workflow w USING (workflowId)
|
||||
|
||||
my $lastActivityFor = $session->db->buildHashRef(<<"");
|
||||
SELECT wi.instanceId, wa.title
|
||||
FROM WorkflowInstance wi
|
||||
JOIN WorkflowActivity wa ON wi.currentActivityId = wa.activityId
|
||||
|
||||
for my $workflowType (qw( Suspended Waiting Running )) {
|
||||
my $workflowsAref = $workflowsHref->{$workflowType};
|
||||
my $workflowCount = @$workflowsAref;
|
||||
|
||||
my $titleHeader = $i18n->get('title header');
|
||||
my $priorityHeader = $i18n->get('priority header');
|
||||
my $activityHeader = $i18n->get('activity header');
|
||||
my $lastStateHeader = $i18n->get('last state header');
|
||||
my $lastRunTimeHeader = $i18n->get('last run time header');
|
||||
$output .= sprintf $i18n->get('workflow type count'), $workflowCount, $workflowType;
|
||||
$output .= '<table style="width: 100%;">';
|
||||
$output .= "<tr><th>$titleHeader</th><th>$priorityHeader</th><th>$activityHeader</th>";
|
||||
$output .= "<th>$lastStateHeader</th><th>$lastRunTimeHeader</th></tr>";
|
||||
|
||||
for my $workflow (@$workflowsAref) {
|
||||
my($priority, $id, $instance) = @$workflow;
|
||||
|
||||
my $originalPriority = ($instance->{priority} - 1) * 10;
|
||||
my $instanceId = $instance->{instanceId};
|
||||
my $title = $workflowTitleFor->{$instanceId} || '(no title)';
|
||||
my $lastActivity = $lastActivityFor->{$instanceId} || '(none)';
|
||||
my $lastRunTime = $instance->{lastRunTime} || '(never)';
|
||||
|
||||
$output .= '<tr>';
|
||||
$output .= "<td>$title</td>";
|
||||
$output .= qq[<td><a id="priority-$instanceId" href="javascript:void(0);" title="Edit Priority" onclick="showEditPriorityForm('$instanceId')">$priority</a>/$originalPriority</td>];
|
||||
$output .= "<td>$lastActivity</td>";
|
||||
$output .= "<td>$instance->{lastState}</td>";
|
||||
$output .= "<td>$lastRunTime</td>";
|
||||
|
||||
if ($isAdmin) {
|
||||
my $run = $i18n->get('run');
|
||||
my $href = $session->url->page(qq[op=runWorkflow;instanceId=$instanceId]);
|
||||
$output .= qq[<td><a href="$href">$run</a></td>];
|
||||
}
|
||||
$output .= "</tr>\n";
|
||||
}
|
||||
$output .= '</table>';
|
||||
}
|
||||
|
||||
$ac->addSubmenuItem($session->url->page("op=addWorkflow"), $i18n->get("add a new workflow"));
|
||||
$ac->addSubmenuItem($session->url->page("op=manageWorkflows"), $i18n->get("manage workflows"));
|
||||
$ac->setHelp('show running workflows', 'Workflow');
|
||||
|
||||
return $ac->render($output, 'show running workflows');
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
|
|
|||
58
lib/WebGUI/i18n/English/Spectre.pm
Normal file
58
lib/WebGUI/i18n/English/Spectre.pm
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package WebGUI::i18n::English::Spectre; ##Be sure to change the package name to match the filename
|
||||
|
||||
our $I18N = { ##hashref of hashes
|
||||
'spectre' => {
|
||||
message => q|Spectre|,
|
||||
lastUpdated => 0,
|
||||
context => q||,
|
||||
},
|
||||
|
||||
'running' => {
|
||||
message => q|Spectre is running.|,
|
||||
lastUpdated => 0,
|
||||
context => q|let the user know that spectre's off|
|
||||
},
|
||||
|
||||
'not running' => {
|
||||
message => q|Spectre is not running.|,
|
||||
lastUpdated => 0,
|
||||
context => q|let the user know that spectre's off|
|
||||
},
|
||||
|
||||
'workflow status error' => {
|
||||
message => q|Spectre is running, but there was an error getting the workflow status.|,
|
||||
lastUpdated => 0,
|
||||
context => q||,
|
||||
},
|
||||
|
||||
'cron status error' => {
|
||||
message => q|Spectre is running, but there was an error getting the cron status.|,
|
||||
lastUpdated => 0,
|
||||
context => q||,
|
||||
},
|
||||
|
||||
'workflow header' => {
|
||||
message => q|There are <a href="%s">%d workflows</a>.<br/>|,
|
||||
lastUpdated => 0,
|
||||
context => q||,
|
||||
},
|
||||
|
||||
'cron header' => {
|
||||
message => q|There are <a href="%s">%d scheduled tasks</a>|,
|
||||
lastUpdated => 0,
|
||||
context => q||,
|
||||
},
|
||||
|
||||
#If the help file documents an Asset, it must include an assetName key
|
||||
#If the help file documents an Macro, it must include an macroName key
|
||||
#If the help file documents a Workflow Activity, it must include an activityName key
|
||||
#If the help file documents a Template Parser, it must include an templateParserName key
|
||||
#For all other types, use topicName
|
||||
'assetName' => {
|
||||
message => q|This should not matter...?|,
|
||||
lastUpdated => 1131394072,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
@ -164,8 +164,9 @@ our $I18N = {
|
|||
|
||||
'show running workflows body' => {
|
||||
message => q|
|
||||
<p>This screen can help you debug problems with workflows by showing which workflows are currently running. The workflows are shown in a table with the name of the workflow, the date it started running. If the workflow has a defined status, then that status will also be shown, along with the date the workflow's status was last updated.</p>
|
||||
<p>The screen will not automatically update. To update the list of running workflows, reload the page.</p>
|
||||
<p>This screen can help you debug problems with workflows by showing which workflows are currently running. The workflows are grouped by status, with their names, current and original priorities, current activities (if any), last state, and when the workflow was last run.</p>
|
||||
<p>You can edit the priority of workflows by clicking on the priority links and submitting the form that appears. You can also run a workflow by clicking the "Run" link in the right column of the table, if present.</p>
|
||||
<p>The screen will not automatically update. To update the list of running workflows, reload the page.</p>
|
||||
|,
|
||||
lastUpdated => 1151719633,
|
||||
},
|
||||
|
|
@ -195,6 +196,108 @@ and add activities to it.</p>
|
|||
lastUpdated => 1151721687,
|
||||
},
|
||||
|
||||
'edit priority success' => {
|
||||
message => q|Workflow priority updated successfully.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority instance not found error' => {
|
||||
message => q|I could not find that workflow. Perhaps it's finished running.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority cancel' => {
|
||||
message => q|cancel|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority update priority' => {
|
||||
message => q|Update Priority|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'spectre not running error' => {
|
||||
message => q|Spectre <b>is not running</b>.<br/>Unable to get workflow information.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'spectre no info error' => {
|
||||
message => q|Spectre <b>is running</b>, but I was not able to get workflow information.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'workflow type count' => {
|
||||
message => q|<h2>%d %s Workflows</h2>|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'title header' => {
|
||||
message => q|Title|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'priority header' => {
|
||||
message => q|Current/Original Priority|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'activity header' => {
|
||||
message => q|Current Activity|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'last state header' => {
|
||||
message => q|Last State|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'last run time header' => {
|
||||
message => q|Last Run Time|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority setting error' => {
|
||||
message => q|There was an error setting the new priority.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority no spectre error' => {
|
||||
message => q|Spectre <b>is not running</b>.<br/>Unable to get workflow information.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority bad request' => {
|
||||
message => q|You have made a bad request.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority no info error' => {
|
||||
message => q|Spectre <b>is running</b>, but I was not able to update the priority.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit priority unknown error' => {
|
||||
message => q|There was an unknown error updating the workflow priority. Please try again later.|,
|
||||
context => q||,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'topicName' => {
|
||||
message => q|Workflow|,
|
||||
context => q|The title of the workflow interface.|,
|
||||
|
|
|
|||
BIN
www/extras/adminConsole/small/spectre.gif
Normal file
BIN
www/extras/adminConsole/small/spectre.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 587 B |
BIN
www/extras/adminConsole/spectre.gif
Normal file
BIN
www/extras/adminConsole/spectre.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue