#!/usr/bin/env perl use v5.10; use strict; use warnings; use Redis::Client; my $queue = 'queue:jobs'; # Name of the queue in redis my $fail = 'queue:fail'; # Queue with all the failed jobs my $timeout = 60; # Timeout for the single job run time my $wait = 5; # Timer for the running tasks my $runnable = 1; # Variable for job looping # We might loose a job when this job is terminated with Ctrl-C. # So let's catch the signals and shutdown the jobrunner after # a full run is completed. sub INT_handler { # Setting the value for the while loop to false == 0 # so the while loop will terminate after the run warn "Shutdown requested - please wait until job is completed.\n"; $runnable = 0; } $SIG{'INT'} = 'INT_handler'; # Instantiate a Redis::Client object my $client = Redis::Client->new(host => 'localhost', port => 6379); # This loop will run forever while ($runnable) { say "Jobrunner is active"; # Get an element from the workqueue or wait until there # is one available # (You might want to use a timeout to see if your worker # is still runnning = $wait ); # # Please note: We are getting an element, if we fail we put # it back in the fail queue my ($list, $job) = $client->blpop($queue, $wait); $job // next; eval { local $SIG{ALRM} = sub { die "Timeout for job ($job)\n"; }; alarm $timeout; # do your job workload here! - probably call something, # do some video encoding, whatever you like # Please remember: Your job will get killed after $wait! say "I have a job"; alarm 0; }; # Check if we ran into an error if ($@) { say "Job fail ($job)"; # Let's catch some errors - add more if you know more fail # reasons for your job runner. given ($@) { when (/^Timeout/) { warn "Job got a timeout\n"; } default { warn "Job failed. Reason($@)\n"; } } # Let's push the failed job to a fail queue $client->rpush($fail => $job); } else { # The job succeeded - nothing to do here say "Job success ($job)"; } } # end of while