App-Koyomi

 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
);



( run in 0.287 second using v1.01-cache-2.11-cpan-05444aca049 )