view release on metacpan or search on metacpan
lib/App/Koyomi/DataSource/Job/Teng.pm view on Meta::CPAN
$now ||= $ctx->now;
my $teng = $self->teng;
# Transaction
my $txn = $teng->txn_scope;
my $now_db = DateTime::Format::MySQL->format_datetime($now);
eval {
# create jobs
my %job = map { $_ => $data->{$_} } qw/user command memo/;
$job{created_on} = $job{updated_at} = $now_db;
my $new_job = $teng->insert('jobs', \%job);
unless ($new_job) {
croakf(q/Insert jobs Failed! data=%s/, ddf(\%job));
}
# create job_times
for my $t (@{$data->{times}}) {
my %time = (
job_id => $new_job->id,
%$t,
created_on => $now_db,
updated_at => $now_db,
);
$teng->insert('job_times', \%time)
or croakf(q/Insert job_times Failed! data=%s/, ddf(\%time));
}
# Initialize semaphore
$ctx->datasource_semaphore->create(
job_id => $new_job->id, ctx => $ctx, now => $now);
};
if ($@) {
lib/App/Koyomi/DataSource/Job/Teng.pm view on Meta::CPAN
$now ||= $ctx->now;
my $teng = $self->teng;
# Transaction
my $txn = $teng->txn_scope;
my $now_db = DateTime::Format::MySQL->format_datetime($now);
eval {
# update jobs
my %job = map { $_ => $data->{$_} } qw/user command memo/;
$job{updated_at} = $now_db;
unless ($teng->update('jobs', \%job, +{ id => $id })) {
croakf(q/Update jobs Failed! id=%d, data=%s/, $id, ddf(\%job));
}
# replace job_times
unless ($teng->delete('job_times', +{ job_id => $id })) {
croakf(q/Delete job_times Failed! id=%d/, $id);
}
for my $t (@{$data->{times}}) {
my %time = (
job_id => $id,
%$t,
created_on => $now_db,
updated_at => $now_db,
);
$teng->insert('job_times', \%time)
or croakf(q/Insert job_times Failed! data=%s/, ddf(\%time));
}
};
if ($@) {
$txn->rollback;
die $@;
}
lib/App/Koyomi/DataSource/Job/Teng/Data.pm view on Meta::CPAN
# Accessor for jobs.columns
{
no strict 'refs';
for my $column (qw/id user command memo/) {
*{ __PACKAGE__ . '::' . $column } = sub {
my $self = shift;
$self->{_job}->$column;
};
}
# DATETIME => DateTime
for my $column (qw/created_on updated_at/) {
*{ __PACKAGE__ . '::' . $column } = sub {
my $self = shift;
DateTime::Format::MySQL->parse_datetime($self->{_job}->$column)
->set_time_zone($self->ctx->config->time_zone);
};
}
}
sub new {
args(
lib/App/Koyomi/DataSource/Semaphore/Teng.pm view on Meta::CPAN
);
$now ||= $ctx->now;
my $teng = $self->teng;
# Transaction
my $txn = $teng->txn_scope;
my $now_db = DateTime::Format::MySQL->format_datetime($now);
eval {
my %semaphore = ( job_id => $job_id );
$semaphore{created_on} = $semaphore{updated_at} = $now_db;
unless ($teng->insert($TABLE, \%semaphore)) {
croakf(q/Insert %s Failed! data=%s/, $TABLE, ddf(\%semaphore));
}
};
if ($@) {
$txn->rollback;
die $@;
}
$txn->commit;
lib/App/Koyomi/DataSource/Semaphore/Teng/Data.pm view on Meta::CPAN
{
no strict 'refs';
for my $column (qw/job_id number run_host run_pid/) {
*{ __PACKAGE__ . '::' . $column } = sub {
my $self = shift;
$self->row->$column;
};
}
# DATETIME => DateTime
for my $column (qw/created_on run_date updated_at/) {
*{ __PACKAGE__ . '::' . $column } = sub {
my $self = shift;
DateTime::Format::MySQL->parse_datetime($self->row->$column)
->set_time_zone($self->ctx->config->time_zone);
};
}
}
sub new {
args(
lib/App/Koyomi/DataSource/Semaphore/Teng/Data.pm view on Meta::CPAN
my $data => 'HashRef',
my $where => 'HashRef',
my $ctx => 'App::Koyomi::Context',
my $now => +{ isa => 'DateTime', optional => 1 },
);
$now ||= $ctx->now;
my $teng = $self->row->handle;
my %stash = %$data;
my %cond = %$where;
for my $col (qw/created_on run_date updated_at/) {
if ($where->{$col}) {
$cond{$col} = DateTime::Format::MySQL->format_datetime($where->{$col});
}
if ($col eq 'updated_at') {
$stash{$col} = DateTime::Format::MySQL->format_datetime($now);
next;
}
if ($data->{$col}) {
$stash{$col} = DateTime::Format::MySQL->format_datetime($data->{$col});
}
}
my $txn = $teng->txn_scope;
my $updated = $self->row->update(\%stash, \%cond);
if ($updated) {
$txn->commit;
return 1;
} else {
$txn->rollback;
return 0;
}
}
1;
lib/App/Koyomi/DataSource/Semaphore/Teng/Schema.pm view on Meta::CPAN
use strict;
use warnings;
use 5.010_001;
use Teng::Schema::Declare;
use version; our $VERSION = 'v0.6.1';
table {
name 'semaphores';
pk 'job_id';
columns qw/job_id number run_host run_pid created_on run_date updated_at/;
};
1;
__END__
=encoding utf-8
=head1 NAME
App::Koyomi::DataSource::Semaphore::Teng::Schema - Teng::Schema class for semaphore datasource
lib/App/Koyomi/Job.pm view on Meta::CPAN
);
use DateTime;
use IPC::Cmd;
use Log::Minimal env_debug => 'KOYOMI_LOG_DEBUG';
use Smart::Args;
use App::Koyomi::Semaphore;
use version; our $VERSION = 'v0.6.1';
our @JOB_FIELDS = qw/id user command memo created_on updated_at/;
our @TIME_FIELDS = qw/id job_id year month day hour minute weekday created_on updated_at/;
{
no strict 'refs';
for my $field (@JOB_FIELDS) {
*{ __PACKAGE__ . '::' . $field } = sub {
my $self = shift;
$self->{_data}->$field;
};
}
}
lib/App/Koyomi/Schedule.pm view on Meta::CPAN
package App::Koyomi::Schedule;
use strict;
use warnings;
use 5.010_001;
use Class::Accessor::Lite (
ro => [qw/ctx config jobs/],
rw => [qw/last_updated_at/],
);
use DateTime;
use Log::Minimal env_debug => 'KOYOMI_LOG_DEBUG';
use Smart::Args;
use App::Koyomi::Job;
use version; our $VERSION = 'v0.6.1';
my $SCHEDULE;
lib/App/Koyomi/Schedule.pm view on Meta::CPAN
sub instance {
args(
my $class,
my $ctx => 'App::Koyomi::Context',
);
$SCHEDULE //= sub {
my %obj = (
ctx => $ctx,
config => $ctx->config,
jobs => undef,
last_updated_at => 0,
);
return bless \%obj, $class;
}->();
return $SCHEDULE;
}
sub update {
my $self = shift;
my $now = shift // $self->ctx->now;
if ($now->epoch - $self->last_updated_at < $self->config->{schedule}{update_interval_seconds}) {
debugf('no need to update schedule');
return;
}
debugf('update schedule');
$self->_update_jobs && $self->last_updated_at($now->epoch);
#debugf(ddf($self->jobs));
}
sub _update_jobs {
my $self = shift;
my $jobs = eval {
App::Koyomi::Job->get_jobs(ctx => $self->ctx);
};
if ($@) {
critf('FAILED to fetch jobs!! ERROR = %s', $@);
schema/mysql/koyomi.ddl view on Meta::CPAN
CREATE TABLE `job_times` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`job_id` int(10) unsigned NOT NULL,
`year` varchar(4) NOT NULL DEFAULT '*' COMMENT 'Ex) 2015',
`month` varchar(2) NOT NULL DEFAULT '*' COMMENT 'Ex) 3, 12',
`day` varchar(2) NOT NULL DEFAULT '*' COMMENT 'Day in month. Ex) 2, 31',
`hour` varchar(2) NOT NULL DEFAULT '*' COMMENT 'Hour in day. Ex) 0, 12, 23',
`minute` varchar(2) NOT NULL DEFAULT '*' COMMENT 'Ex) 0, 59',
`weekday` varchar(1) NOT NULL DEFAULT '*' COMMENT 'Day of week as number. Compatiable with crontab. Ex) 0, 6, 7',
`created_on` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY idx_job_id (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `job_times`
--
LOCK TABLES `job_times` WRITE;
schema/mysql/koyomi.ddl view on Meta::CPAN
DROP TABLE IF EXISTS `jobs`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `jobs` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user` varchar(32) NOT NULL DEFAULT '' COMMENT 'Command executor in the system',
`command` varchar(4096) NOT NULL COMMENT 'Shell command to execute',
`memo` varchar(512) NOT NULL DEFAULT '',
`created_on` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `jobs`
--
LOCK TABLES `jobs` WRITE;
/*!40000 ALTER TABLE `jobs` DISABLE KEYS */;
schema/mysql/koyomi.ddl view on Meta::CPAN
DROP TABLE IF EXISTS `semaphores`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `semaphores` (
`job_id` int(10) unsigned NOT NULL COMMENT 'jobs.id',
`number` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Semaphore resource remains (Not in use)',
`run_host` varchar(256) NOT NULL DEFAULT '' COMMENT 'On which host the last job ran',
`run_pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Tha last process id',
`run_date` datetime NOT NULL DEFAULT '1970-01-01 00:00:00',
`created_on` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `semaphores`
--
LOCK TABLES `semaphores` WRITE;
/*!40000 ALTER TABLE `semaphores` DISABLE KEYS */;
schema/sqlite/koyomi.ddl view on Meta::CPAN
CREATE TABLE job_times (
id INTEGER PRIMARY KEY,
job_id INTEGER,
year TEXT,
month TEXT,
day TEXT,
hour TEXT,
minute TEXT,
weekday TEXT,
created_on TEXT,
updated_at TEXT
);
CREATE TABLE jobs (
id INTEGER PRIMARY KEY,
user TEXT,
command TEXT,
memo TEXT,
created_on TEXT,
updated_at TEXT
);