diff --git a/.gitignore b/.gitignore index 2ecdfe1..027fb18 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ myapp.conf hypnotoad.pid *.db +*.db-wal +*.db-shm *~ /images *.swp diff --git a/README.md b/README.md index 0ecea78..065845c 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,41 @@ cpanm --installdeps . --with-feature postgres PEAR_TEST_PG=1 prove -lr ``` +# Minion + +to set up minion support, you will need to create a database and user for +minion to connect to. In production his should be a PostgreSQL database, +however an SQLite db can be used in testing. + +To use the SQLite version, run the following commands: + +``` +cpanm --installdeps --with-feature sqlite . +``` + +And then add the following to your configuration file: + +``` + minion => { + SQLite => 'sqlite:minion.db', + }, +``` + +This will then use an SQLite db for the minion backend, at minion.db + + +## Example PostgreSQL setup + +``` +# Example commands - probably not the best ones +# TODO come back and improve these with proper ownership and DDL rights +sudo -u postgres createuser minion +sudo -u postgres createdb localloop_minion +sudo -u postgres psql +psql=# alter user minion with encrypted password 'abc123'; +psql=# grant all privileges on database localloop_minion to minion; +``` + # Dev notes ## Local test database diff --git a/cpanfile b/cpanfile index 4d7839d..9aed545 100644 --- a/cpanfile +++ b/cpanfile @@ -40,6 +40,10 @@ feature 'postgres', 'PostgreSQL Support' => sub { requires 'Test::PostgreSQL'; }; +feature 'sqlite', 'SQLite Support' => sub { + requires 'Minion::Backend::SQLite'; +}; + feature 'codepoint-open', 'Code Point Open manipulation' => sub { requires 'Geo::UK::Postcode::CodePointOpen'; }; diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 3dad2b6..e6248e6 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -49,6 +49,7 @@ sub startup { $self->plugin('Pear::LocalLoop::Plugin::Currency'); $self->plugin('Pear::LocalLoop::Plugin::Postcodes'); $self->plugin('Pear::LocalLoop::Plugin::TemplateHelpers'); + $self->plugin('Pear::LocalLoop::Plugin::Minion'); $self->plugin('Authentication' => { 'load_user' => sub { @@ -196,6 +197,12 @@ sub startup { my $admin_routes = $r->under('/admin')->to('admin#under'); + if ( defined $config->{minion} ) { + $self->plugin( 'Minion::Admin' => { + return_to => '/admin/home', + route => $admin_routes->any('/minion'), + } ); + } $admin_routes->get('/home')->to('admin#home'); $admin_routes->get('/tokens')->to('admin-tokens#index'); diff --git a/lib/Pear/LocalLoop/Plugin/Minion.pm b/lib/Pear/LocalLoop/Plugin/Minion.pm new file mode 100644 index 0000000..54a592b --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion.pm @@ -0,0 +1,38 @@ +package Pear::LocalLoop::Plugin::Minion; +use Mojo::Base 'Mojolicious::Plugin'; + +use Mojo::Loader qw/ find_modules load_class /; + +sub register { + my ( $plugin, $app, $cong ) = @_; + + if ( defined $app->config->{minion} ) { + $app->log->debug('Setting up Minion tasks'); + $app->plugin('Minion' => $app->config->{minion} ); + + $app->log->debug('Loaded Minion Job packages:'); + + my $job_namespace = __PACKAGE__ . '::Job'; + my @modules = find_modules $job_namespace; + for my $package ( @modules ) { + my ( $job ) = $package =~ /${job_namespace}::(.*)$/; + $app->log->debug( $package ); + load_class $package; + $app->minion->add_task( + $job => sub { + my ( $job, @args ) = @_; + my $job_runner = $package->new( + job => $job, + ); + $job_runner->run( @args ); + } + ); + } + # $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] ); + } else { + $app->log->debug('No Minion Config'); + } + +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job.pm new file mode 100644 index 0000000..2006845 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job.pm @@ -0,0 +1,12 @@ +package Pear::LocalLoop::Plugin::Minion::Job; +use Mojo::Base -base; + +has [ qw/ job / ]; + +has app => sub { shift->job->app }; + +sub run { + die ( __PACKAGE__ . " must implement run sub" ); +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm new file mode 100644 index 0000000..142df7f --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm @@ -0,0 +1,12 @@ +package Pear::LocalLoop::Plugin::Minion::Job::leaderboards_recalc; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; + +sub run { + my ( $self, @args ) = @_; + + my $leaderboard_rs = $self->app->schema->resultset('Leaderboard'); + + $leaderboard_rs->recalculate_all; +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm new file mode 100644 index 0000000..e0cfcf0 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm @@ -0,0 +1,13 @@ +package Pear::LocalLoop::Plugin::Minion::Job::test; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; + +sub run { + my ( $self, @args ) = @_; + + $self->job->app->log->debug( 'Testing Job' ); + for my $arg ( @args ) { + $self->job->app->log->debug( $arg ); + } +} + +1; diff --git a/pear-local_loop.conf b/pear-local_loop.conf index 6810316..40e8c2b 100644 --- a/pear-local_loop.conf +++ b/pear-local_loop.conf @@ -3,4 +3,7 @@ user => undef, pass => undef, key => "a", -}; + minion => { + SQLite => 'sqlite:minion.db', + }, +};