X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FTak%2FRouter.pm;h=5c2502b7eb017cb8881706da2ff545e314b36d5c;hb=2791fd73b196072f047b2b3d746b64be53312ca3;hp=58b73bf7d64e283c3668a73ee76d3ee2bfcb881f;hpb=8b6c1f59e563ab0ccdd728c327b2c994833fcd87;p=scpubgit%2FTak.git diff --git a/lib/Tak/Router.pm b/lib/Tak/Router.pm index 58b73bf..5c2502b 100644 --- a/lib/Tak/Router.pm +++ b/lib/Tak/Router.pm @@ -1,107 +1,45 @@ package Tak::Router; -use Tak::Request; -use Tak::ServiceManager; +use Tak::MetaService; +use Scalar::Util qw(weaken); use Moo; -has channel => (is => 'ro', required => 1); +has services => (is => 'ro', default => sub { {} }); -has local_request_handlers => (is => 'ro', default => sub { {} }); - -has requests_received => (is => 'ro', default => sub { {} }); - -has last_serial => (is => 'ro',default => sub { 'A0000' }); - -sub next_serial { ++($_[0]->{last_serial}) } - -has requests_sent => (is => 'ro', default => sub { {} }); - -sub run { shift->run_until } - -sub run_until { - my ($self, $done) = @_; - while (!$_[1] and my $message = $self->channel->receive) { - $self->receive(@$message); - } +sub BUILD { + my ($self) = @_; + $self->register(meta => Tak::MetaService->new(router => $self)); } -sub receive { - my ($self, $type, @payload) = @_; - unless ($type) { - $self->channel->send(MISTAKE => message_format => "No message type"); - return; - } - unless (@payload) { - $self->channel->send(MISTAKE => message_format => "Tag missing"); - return; - } - unless (@payload > 1) { - $self->channel->send(MISTAKE => message_format => "No payload"); - } - if ($type eq 'REQUEST') { - $self->receive_request(@payload); - return; - } - if ($type eq 'RESPONSE') { - $self->receive_response(@payload); - return; - } +sub start_request { + my ($self, $req, $target, @payload) = @_; + return $req->mistake("Reached router with no target") + unless $target; + return $req->failure("Reached router with invalid target ${target}") + unless my $next = $self->services->{$target}; + $next->start_request($req, @payload); } -sub receive_request { - my ($self, $tag, $handler_name, @payload) = @_; - if ($self->requests_received->{$tag}) { - $self->channel->send( - MISTAKE => request_tag => "Request for ${tag} in process" - ); - return; - } - my $handler = $self->local_request_handlers->{$handler_name}; - unless ($handler) { - $self->send_response( - $tag => MISTAKE => handler_name => "No such handler ${handler_name}" - ); - return; - } - my $request - = $self->requests_received->{$tag} - = Tak::Request->new( - tag => $tag, respond_to => $self, respond_with => 'send_response', - ); - $handler->start_request($request => @payload); -} - -sub send_response { - my ($self, $tag, @result) = @_; - delete $self->requests_received->{$tag}; - $self->channel->send(RESPONSE => $tag => @result); +sub receive { + my ($self, $target, @payload) = @_; + return unless $target; + return unless my $next = $self->services->{$target}; + $next->receive(@payload); } -sub send_request { - my ($self, $respond_to, $respond_with, @payload) = @_; - my $tag = $self->next_serial; - my $request - = $self->requests_sent->{$tag} - = Tak::Request->new( - tag => $tag, - respond_to => $respond_to, - respond_with => $respond_with, - ); - $self->channel->send(REQUEST => $tag => @payload); - return $request; +sub register { + my ($self, $name, $service) = @_; + $self->services->{$name} = $service; } -sub receive_response { - my ($self, $tag, @result) = @_; - my $request = delete $self->requests_sent->{$tag}; - $request->respond(@result); +sub register_weak { + my ($self, $name, $service) = @_; + weaken($self->services->{$name} = $service); } -sub register { - my ($self, $name, $service) = @_; - $self->local_request_handlers->{$name} = Tak::ServiceManager->new( - service => $service - ); +sub deregister { + my ($self, $name) = @_; + delete $self->services->{$name} } 1;