# is a gearman worker # gearman worker provides # - registering all methods in this class # - execute those methods through gearman calls # - deamonizing the process package RWDE::Gearman::Worker; use strict; use warnings; use Error qw(:try); use Storable qw( thaw nfreeze ); use Gearman::Worker; use RWDE::Configuration; use RWDE::DB::DbRegistry; use RWDE::Exceptions; use base qw(RWDE::Runnable); sub new { my ($proto, $params) = @_; my $class = ref($proto) || $proto; my $gear = Gearman::Worker->new(); my $self = { gear => $gear }; bless $self, $class; #connect to the server $gear->job_servers(@{ RWDE::Configuration->GearHost }); #register a test method (every class should have one - for monitoring purposes it is in the caller's namespace) $self->register_method({ methods => 'ping' }); #initialize give a chance to the inheriting class to register its exposed methods $self->initialize(); return $self; } sub get_gear { my ($self, $params) = @_; throw RWDE::DevelException({ info => 'No worker present' }) unless defined $self->{gear}; return $self->{gear}; } sub initialize { my ($self, $params) = @_; warn 'RWDE::Gearman::Worker->initialize should be overriden in subclasses, only ping will be exported'; return (); } sub register_method { my ($self, $params) = @_; my $worker = $self->get_gear(); my $namespace = ref $self; my $methods = $$params{'methods'}; if (ref $methods ne 'ARRAY') { $methods = [$methods]; } foreach my $method (@{$methods}) { $worker->register_function($namespace . '::' . $method, \&RWDE::Gearman::Worker::handler); } return (); } sub start { my ($self, $params) = @_; my $gear = $self->get_gear(); $self->syslog_msg('info', 'Worker ' . $self . 'Starting...'); while (1) { $gear->work(); } return (); } #do interpretation of error results here - return back $ex and then end user can call throw on that sub handler { my ($args) = @_; my $result; try { my $params = thaw(${ $args->argref }); my $call = $$params{method}; $call =~ m/(.*)::(.*)/; my $namespace = $1; my $function = $2; @$result = $namespace->$function($params); } catch Error with { my $ex = shift; warn $ex; #if we have an error, return it $result = $ex; }; my $result_ref = \$result; return nfreeze $result_ref; } sub ping { my ($self, $params) = @_; return 1; } 1;