From ee71ba3372b47b7de1e30d56db92c1315ae1e104 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Fri, 29 Oct 2010 15:42:14 +0200 Subject: [PATCH] Hintergrundjobs: DB-Model und allgemeine Modelimplementation mit ersten Test-Jobs --- SL/BackgroundJob/Base.pm | 31 +++++++++++ SL/BackgroundJob/CleanBackgroundJobHistory.pm | 29 +++++++++++ SL/BackgroundJob/Test.pm | 13 +++++ SL/DB/BackgroundJob.pm | 51 ++++++++++++++++++- SL/DB/Manager/BackgroundJob.pm | 17 ++++++- 5 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 SL/BackgroundJob/Base.pm create mode 100644 SL/BackgroundJob/CleanBackgroundJobHistory.pm create mode 100644 SL/BackgroundJob/Test.pm diff --git a/SL/BackgroundJob/Base.pm b/SL/BackgroundJob/Base.pm new file mode 100644 index 000000000..44702d84d --- /dev/null +++ b/SL/BackgroundJob/Base.pm @@ -0,0 +1,31 @@ +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; diff --git a/SL/BackgroundJob/CleanBackgroundJobHistory.pm b/SL/BackgroundJob/CleanBackgroundJobHistory.pm new file mode 100644 index 000000000..117a4d4ad --- /dev/null +++ b/SL/BackgroundJob/CleanBackgroundJobHistory.pm @@ -0,0 +1,29 @@ +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; diff --git a/SL/BackgroundJob/Test.pm b/SL/BackgroundJob/Test.pm new file mode 100644 index 000000000..01c8569b4 --- /dev/null +++ b/SL/BackgroundJob/Test.pm @@ -0,0 +1,13 @@ +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; diff --git a/SL/DB/BackgroundJob.pm b/SL/DB/BackgroundJob.pm index f4edf2d30..b9e00c4d3 100644 --- a/SL/DB/BackgroundJob.pm +++ b/SL/DB/BackgroundJob.pm @@ -3,16 +3,65 @@ package SL::DB::BackgroundJob; 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; diff --git a/SL/DB/Manager/BackgroundJob.pm b/SL/DB/Manager/BackgroundJob.pm index 178f9d37a..35a773d6e 100644 --- a/SL/DB/Manager/BackgroundJob.pm +++ b/SL/DB/Manager/BackgroundJob.pm @@ -15,8 +15,21 @@ sub cleanup { } 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; -- 2.20.1