--- /dev/null
+package SL::BackgroundJob::Base;
+
+use strict;
+
+use parent qw(Rose::Object);
+
+use SL::DB::BackgroundJob;
+
+sub create_standard_job {
+ my $self_or_class = shift;
+ my $cron_spec = shift;
+
+ my $package = ref($self_or_class) || $self_or_class;
+ $package =~ s/SL::BackgroundJob:://;
+
+ my %params = (cron_spec => $cron_spec || '* * * * *',
+ type => 'interval',
+ active => 1,
+ package_name => $package);
+
+ my $job = SL::DB::Manager::BackgroundJob->find_by(package_name => $params{package_name});
+ if (!$job) {
+ $job = SL::DB::BackgroundJob->new(%params)->update_next_run_at;
+ } else {
+ $job->assign_attributes(%params)->update_next_run_at;
+ }
+
+ return $job;
+}
+
+1;
--- /dev/null
+package SL::BackgroundJob::CleanBackgroundJobHistory;
+
+use parent qw(SL::BackgroundJob::Base);
+
+use SL::DB::BackgroundJobHistory;
+
+sub create_job {
+ $_[0]->create_standard_job('0 3 * * *'); # daily at 3:00 am
+}
+
+sub run {
+ my $self = shift;
+ my $db_obj = shift;
+
+ my $options = $db_obj->data_as_hash;
+ $options->{retention_success} ||= 14;
+ $options->{retention_failure} ||= 3 * 30;
+
+ my $today = DateTime->today_local;
+
+ for my $status (qw(success failure)) {
+ SL::DB::Manager::BackgroundJobHistory->delete_all(where => [ status => $status,
+ run_at => { lt => $today->clone->subtract(days => $options->{"retention_${status}"}) } ]);
+ }
+
+ return 1;
+}
+
+1;
--- /dev/null
+package SL::BackgroundJob::Test;
+
+use parent qw(SL::BackgroundJob::Base);
+
+sub run {
+ my $self = shift;
+ my $db_obj = shift;
+
+ $::lxdebug->message(0, "Test job is being executed.");
+}
+
+
+1;
use strict;
use DateTime::Event::Cron;
+use English qw(-no_match_vars);
use SL::DB::MetaSetup::BackgroundJob;
use SL::DB::Manager::BackgroundJob;
+use SL::DB::BackgroundJobHistory;
+
+use SL::BackgroundJob::Test;
+
sub update_next_run_at {
my $self = shift;
my $cron = DateTime::Event::Cron->new_from_cron($self->cron_spec || '* * * * *');
- $self->update_attributes(next_run_at => $cron->next->set_time_zone($::locale->get_local_time_zone));
+ $self->update_attributes(next_run_at => $cron->next(DateTime->now_local));
return $self;
}
+sub run {
+ my $self = shift;
+
+ my $package = "SL::BackgroundJob::" . $self->package_name;
+ my $run_at = DateTime->now_local;
+ my $history;
+
+ eval {
+ my $result = $package->new->run($self);
+
+ $history = SL::DB::BackgroundJobHistory
+ ->new(package_name => $self->package_name,
+ run_at => $run_at,
+ status => 'success',
+ result => $result,
+ data => $self->data);
+ $history->save;
+
+ 1;
+ };
+
+ if ($EVAL_ERROR) {
+ $history = SL::DB::BackgroundJobHistory
+ ->new(package_name => $self->package_name,
+ run_at => $run_at,
+ status => 'failure',
+ error => $EVAL_ERROR,
+ data => $self->data);
+ $history->save;
+ }
+
+ $self->assign_attributes(last_run_at => $run_at)->update_next_run_at;
+
+ return $history;
+}
+
+sub data_as_hash {
+ my $self = shift;
+ return {} if !$self->data;
+ return $self->data if ref($self->{data}) eq 'HASH';
+ return YAML::Load($self->{data}) if !ref($self->{data});
+ return {};
+}
+
1;
}
sub get_all_need_to_run {
- my $class = shift;
- return $class->get_all(where => [ and => [ active => 1, next_run_at => { le => DateTime->now_local } ] ]);
+ my $class = shift;
+
+ my $now = DateTime->now_local;
+ my @interval_args = (and => [ type => 'interval',
+ active => 1,
+ next_run_at => { le => $now } ]);
+ my @once_args = (and => [ type => 'once',
+ active => 1,
+ last_run_at => undef,
+ or => [ cron_spec => undef,
+ cron_spec => '',
+ next_run_at => undef,
+ next_run_at => { le => $now } ] ]);
+
+ return $class->get_all(where => [ or => [ @interval_args, @once_args ] ]);
}
1;