diff --git a/lib/Spectre/Cron.pm b/lib/Spectre/Cron.pm new file mode 100644 index 000000000..f9e473ecf --- /dev/null +++ b/lib/Spectre/Cron.pm @@ -0,0 +1,133 @@ +package Spectre::Cron; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2006 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; +use DateTime; +use DateTime::Cron::Simple; +use WebGUI::Session; + +#------------------------------------------------------------------- + +=head2 addJob ( config, job ) + +Adds a job to the cron monitoring queue. + +=head3 config + +The filename of the configuration file for the site this job belongs to. + +=head3 job + +A hash reference containing the properties of the job from the WorkflowSchedule table. + +=cut + +sub addJob { + my $self = shift; + my $config = shift; + my $job = shift; + return 0 unless ($job->{enabled}); + $self->{_jobs}{$job->{jobId}} = { + config=>$config, + schedule=>join(" ", $job->{minuteOfHour}, $job->{hourOfDay}, $job->{dayOfMonth}, $job->{monthOfYear}, $job->{dayOfWeek}), + workflowId=>$job->{workflowId} + } +} + + +#------------------------------------------------------------------- + +=head2 checkSchedules ( ) + +Checks all the schedules of the jobs in the queue and triggers a workflow if a schedule matches. + +=cut + +sub checkSchedules { + my $self = shift + my $now = DateTime->from_epoch(epoch=>time()); + foreach my $jobId (keys %{$self->{_jobs}}) { + my $cron = DateTime::Cron::Simple->new($self->{_jobs}{$jobId}{schedule}); + if ($cron->validate_time($now) { + # kick off an event here once we know what that api looks like + } + } +} + + +#------------------------------------------------------------------- + +=head2 deleteJob ( jobId ) + +Removes a job from the monitoring queue. + +=head3 jobId + +The unique id of the job to remove. + +=cut + +sub deleteJob { + my $self = shift; + delete $self->{_jobs}{shift}; +} + + +#------------------------------------------------------------------- + +=head2 DESTROY ( ) + +Deconstructor. + +=cut + +sub DESTROY { + my $self = shift; + undef $self; +} + + +#------------------------------------------------------------------- + +=head2 new ( webguiRoot ) + +Constructor. Loads all schedules from WebGUI sites into it's job queue. + +=head3 webguiRoot + +The path to the root of the WebGUI installation. + +=cut + +sub new { + my $class = shift; + my $webguiRoot = shift; + my $self = {_webguiRoot=>$webguiRoot}; + bless $self, $class; + my $configs = WebGUI::Config->readAllConfigs($webguiRoot); + foreach my $config (keys %{$configs}) { + my $session = WebGUI::Session->open($webguiRoot, $config); + my $result = $session->db->read("select * from WorkflowSchedule"); + while (my $data = $result->hashRef) { + $self->addJob($config, $data); + } + $session->close; + } +} + + +1; + diff --git a/lib/Spectre/ProcessManager.pm b/lib/Spectre/ProcessManager.pm new file mode 100644 index 000000000..a0b7e7e99 --- /dev/null +++ b/lib/Spectre/ProcessManager.pm @@ -0,0 +1,117 @@ +package Spectre::ProcessManager; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2006 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; +use Proc::Background; + +#------------------------------------------------------------------- + +=head2 cleanUp ( ) + +Cleans up the process list by clearning out old processes that have completed. + +=cut + +sub cleanUp { + my $self = shift; + my @newList = (); + foreach my $process (@{$self->{_processList}}) { + push(@newList, $process) if ($process->alive); + } + $self->{_processList} = \@newList; +} + +#------------------------------------------------------------------- + +=head2 createProcess ( command ) + +Spawns a new process. + +=head3 command + +The commandline to execute under the new process. + +=cut + +sub createProcess { + my $self = shift; + my $command = shift; + my $process = Proc::Background->new({'die_upon_destroy' => 1}, $command); + push(@{$self->{_processList}}, $process); +} + +#------------------------------------------------------------------- + +=head2 DESTROY ( ) + +Deconstructor. + +=cut + +sub DESTROY { + my $self = shift; + $self->killAllProcesses; + undef $self; +} + +#------------------------------------------------------------------- + +=head2 getProcessCount ( ) + +Returns an integer representing the number of processes currently running. This runs cleanUp() before counting to ensure an accurate count. + +=cut + +sub getProcessCount { + my $self = shift; + $self->cleanUp; + return scalar(@{$self->{_processList}}); +} + + +#------------------------------------------------------------------- + +=head2 killAllProcesses ( ) + +Kills all of the running processes. + +=cut + +sub killAllProcesses { + my $self = shift; + foreach my $process (@{$self->{_processList}}) { + $process->die; + } + $self->{_processList} = (); +} + + +#------------------------------------------------------------------- + +=head2 new ( ) + +Constructor. + +=cut + +sub new { + my $class = shift; + bless {_processList} => ()}, $class; +} + +1; + + diff --git a/lib/Spectre/Workflow.pm b/lib/Spectre/Workflow.pm new file mode 100644 index 000000000..2d2d74a2e --- /dev/null +++ b/lib/Spectre/Workflow.pm @@ -0,0 +1,124 @@ +package Spectre::Workflow; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2006 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; + + +#------------------------------------------------------------------- + +=head2 addJob ( config, job ) + +Adds a workflow job to the workflow processing queue. + +=head3 config + +The config file name for the site that this job belongs to. + +=head3 job + +A hash reference containing a row of data from the WorkflowInstance table. + +=cut + +sub addJob { + my $self = shift; + my $config = shift; + my $job = shift; + $self->{"_priority".$job->{priority}}{$job->{instanceId}} = { + config=>$config, + status=>"waiting" + }; +} + +#------------------------------------------------------------------- + +=head2 deleteJob ( instanceId ) + +Removes a workflow job from the processing queue. + +=cut + +sub deleteJob { + my $self = shift; + delete $self->{_priority1}{shift}; + delete $self->{_priority2}{shift}; + delete $self->{_priority3}{shift}; +} + + +#------------------------------------------------------------------- + +=head2 DESTROY ( ) + +Deconstructor. + +=cut + +sub DESTROY { + my $self = shift; + undef $self; +} + + +#------------------------------------------------------------------- + +=head2 getNextJob ( ) + +=cut + +sub getNextJob { + my $self = shift; + foreach my $priority (1..3) { + foreach my $instanceId (keys %{$self->{"_priority".$priority}}) { + if ($self->{"_priority".$priority}{status} eq "waiting") { + + } + } + return undef; +} + +#------------------------------------------------------------------- + +=head2 new ( webguiRoot ) + +Constructor. Loads all active workflows from each WebGUI site and begins executing them. + +=head3 webguiRoot + +The path to the root of the WebGUI installation. + +=cut + +sub new { + my $class = shift; + my $webguiRoot = shift; + my $self = {_webguiRoot=>$webguiRoot}; + bless $self, $class; + my $configs = WebGUI::Config->readAllConfigs($webguiRoot); + foreach my $config (keys %{$configs}) { + my $session = WebGUI::Session->open($webguiRoot, $config); + my $result = $session->db->read("select * from WorkflowInstance"); + while (my $data = $result->hashRef) { + $self->addJob($config, $data); + } + $session->close; + } +} + + +1; + +