create world object, repl script
[scpubgit/Tak.git] / lib / Tak / Router.pm
CommitLineData
36cf3bcb 1package Tak::Router;
2
3use Tak::Request;
8b6c1f59 4use Tak::ServiceManager;
36cf3bcb 5use Moo;
6
7has channel => (is => 'ro', required => 1);
8
9has local_request_handlers => (is => 'ro', default => sub { {} });
10
11has requests_received => (is => 'ro', default => sub { {} });
12
13has last_serial => (is => 'ro',default => sub { 'A0000' });
14
15sub next_serial { ++($_[0]->{last_serial}) }
16
17has requests_sent => (is => 'ro', default => sub { {} });
18
19sub run { shift->run_until }
20
21sub run_until {
22 my ($self, $done) = @_;
23 while (!$_[1] and my $message = $self->channel->receive) {
24 $self->receive(@$message);
25 }
26}
27
28sub receive {
29 my ($self, $type, @payload) = @_;
30 unless ($type) {
31 $self->channel->send(MISTAKE => message_format => "No message type");
32 return;
33 }
34 unless (@payload) {
35 $self->channel->send(MISTAKE => message_format => "Tag missing");
36 return;
37 }
38 unless (@payload > 1) {
39 $self->channel->send(MISTAKE => message_format => "No payload");
40 }
41 if ($type eq 'REQUEST') {
42 $self->receive_request(@payload);
43 return;
44 }
45 if ($type eq 'RESPONSE') {
46 $self->receive_response(@payload);
47 return;
48 }
49}
50
51sub receive_request {
52 my ($self, $tag, $handler_name, @payload) = @_;
53 if ($self->requests_received->{$tag}) {
54 $self->channel->send(
55 MISTAKE => request_tag => "Request for ${tag} in process"
56 );
57 return;
58 }
59 my $handler = $self->local_request_handlers->{$handler_name};
60 unless ($handler) {
61 $self->send_response(
62 $tag => MISTAKE => handler_name => "No such handler ${handler_name}"
63 );
64 return;
65 }
66 my $request
67 = $self->requests_received->{$tag}
68 = Tak::Request->new(
ca30c15e 69 tag => $tag, respond_to => $self, respond_with => 'send_response',
36cf3bcb 70 );
71 $handler->start_request($request => @payload);
72}
73
74sub send_response {
75 my ($self, $tag, @result) = @_;
76 delete $self->requests_received->{$tag};
77 $self->channel->send(RESPONSE => $tag => @result);
78}
79
80sub send_request {
ca30c15e 81 my ($self, $respond_to, $respond_with, @payload) = @_;
36cf3bcb 82 my $tag = $self->next_serial;
83 my $request
84 = $self->requests_sent->{$tag}
85 = Tak::Request->new(
86 tag => $tag,
ca30c15e 87 respond_to => $respond_to,
88 respond_with => $respond_with,
36cf3bcb 89 );
90 $self->channel->send(REQUEST => $tag => @payload);
91 return $request;
92}
93
94sub receive_response {
95 my ($self, $tag, @result) = @_;
96 my $request = delete $self->requests_sent->{$tag};
97 $request->respond(@result);
98}
99
8b6c1f59 100sub register {
101 my ($self, $name, $service) = @_;
102 $self->local_request_handlers->{$name} = Tak::ServiceManager->new(
103 service => $service
104 );
105}
106
36cf3bcb 1071;