… | |
… | |
84 | |
84 | |
85 | use base "Exporter"; |
85 | use base "Exporter"; |
86 | |
86 | |
87 | our $VERSION = '0.02'; |
87 | our $VERSION = '0.02'; |
88 | our @EXPORT = qw( |
88 | our @EXPORT = qw( |
89 | NODE $NODE $PORT snd rcv _any_ |
89 | NODE $NODE $PORT snd rcv mon del _any_ |
90 | create_port create_port_on |
90 | create_port create_port_on |
91 | create_miniport |
91 | create_miniport |
92 | become_slave become_public |
92 | become_slave become_public |
93 | ); |
93 | ); |
94 | |
94 | |
… | |
… | |
118 | JSON is used, then only strings, numbers and arrays and hashes consisting |
118 | JSON is used, then only strings, numbers and arrays and hashes consisting |
119 | of those are allowed (no objects). When Storable is used, then anything |
119 | of those are allowed (no objects). When Storable is used, then anything |
120 | that Storable can serialise and deserialise is allowed, and for the local |
120 | that Storable can serialise and deserialise is allowed, and for the local |
121 | node, anything can be passed. |
121 | node, anything can be passed. |
122 | |
122 | |
|
|
123 | =item $guard = mon $portid, $cb->() |
|
|
124 | |
|
|
125 | Monitor the given port and call the given callback when the port is |
|
|
126 | destroyed or connection to it's node is lost. |
|
|
127 | |
|
|
128 | #TODO |
|
|
129 | |
|
|
130 | =cut |
|
|
131 | |
|
|
132 | sub mon { |
|
|
133 | my ($noderef, $port) = split /#/, shift, 2; |
|
|
134 | |
|
|
135 | my $node = AnyEvent::MP::Base::add_node $noderef; |
|
|
136 | |
|
|
137 | my $cb = shift; |
|
|
138 | |
|
|
139 | $node->monitor ($port, $cb); |
|
|
140 | |
|
|
141 | defined wantarray |
|
|
142 | and AnyEvent::Util::guard { $node->unmonitor ($port, $cb) } |
|
|
143 | } |
|
|
144 | |
123 | =item $local_port = create_port |
145 | =item $local_port = create_port |
124 | |
146 | |
125 | Create a new local port object. See the next section for allowed methods. |
147 | Create a new local port object. See the next section for allowed methods. |
126 | |
148 | |
127 | =cut |
149 | =cut |
128 | |
150 | |
129 | sub create_port { |
151 | sub create_port { |
130 | my $id = "$AnyEvent::MP::Base::UNIQ." . ++$AnyEvent::MP::Base::ID; |
152 | my $id = "$AnyEvent::MP::Base::UNIQ." . $AnyEvent::MP::Base::ID++; |
131 | |
153 | |
132 | my $self = bless { |
154 | my $self = bless { |
133 | id => "$NODE#$id", |
155 | id => "$NODE#$id", |
134 | names => [$id], |
156 | names => [$id], |
135 | }, "AnyEvent::MP::Port"; |
157 | }, "AnyEvent::MP::Port"; |
… | |
… | |
156 | }; |
178 | }; |
157 | |
179 | |
158 | $self |
180 | $self |
159 | } |
181 | } |
160 | |
182 | |
161 | =item $portid = create_miniport { } |
183 | =item $portid = miniport { my @msg = @_; $finished } |
162 | |
184 | |
163 | Creates a "mini port", that is, a port without much #TODO |
185 | Creates a "mini port", that is, a very lightweight port without any |
|
|
186 | pattern matching behind it, and returns its ID. |
164 | |
187 | |
165 | =cut |
188 | The block will be called for every message received on the port. When the |
|
|
189 | callback returns a true value its job is considered "done" and the port |
|
|
190 | will be destroyed. Otherwise it will stay alive. |
166 | |
191 | |
|
|
192 | The message will be passed as-is, no extra argument (i.e. no port id) will |
|
|
193 | be passed to the callback. |
|
|
194 | |
|
|
195 | If you need the local port id in the callback, this works nicely: |
|
|
196 | |
|
|
197 | my $port; $port = miniport { |
|
|
198 | snd $otherport, reply => $port; |
|
|
199 | }; |
|
|
200 | |
|
|
201 | =cut |
|
|
202 | |
167 | sub create_miniport(&) { |
203 | sub miniport(&) { |
168 | my $cb = shift; |
204 | my $cb = shift; |
169 | my $id = "$AnyEvent::MP::Base::UNIQ." . ++$AnyEvent::MP::Base::ID; |
205 | my $id = "$AnyEvent::MP::Base::UNIQ." . $AnyEvent::MP::Base::ID++; |
170 | |
206 | |
171 | $AnyEvent::MP::Base::PORT{$id} = sub { |
207 | $AnyEvent::MP::Base::PORT{$id} = sub { |
172 | # unshift @_, "$NODE#$id"; |
|
|
173 | &$cb |
208 | &$cb |
174 | and delete $AnyEvent::MP::Base::PORT{$id}; |
209 | and del $id; |
175 | }; |
210 | }; |
176 | |
211 | |
177 | "$NODE#$id" |
212 | "$NODE#$id" |
178 | } |
213 | } |
179 | |
214 | |
… | |
… | |
193 | =cut |
228 | =cut |
194 | |
229 | |
195 | use overload |
230 | use overload |
196 | '""' => sub { $_[0]{id} }, |
231 | '""' => sub { $_[0]{id} }, |
197 | fallback => 1; |
232 | fallback => 1; |
|
|
233 | |
|
|
234 | sub TO_JSON { $_[0]{id} } |
198 | |
235 | |
199 | =item $port->rcv (type => $callback->($port, @msg)) |
236 | =item $port->rcv (type => $callback->($port, @msg)) |
200 | |
237 | |
201 | =item $port->rcv ($smartmatch => $callback->($port, @msg)) |
238 | =item $port->rcv ($smartmatch => $callback->($port, @msg)) |
202 | |
239 | |
… | |
… | |
262 | =cut |
299 | =cut |
263 | |
300 | |
264 | sub destroy { |
301 | sub destroy { |
265 | my ($self) = @_; |
302 | my ($self) = @_; |
266 | |
303 | |
|
|
304 | AnyEvent::MP::Base::del $self->{id}; |
|
|
305 | |
267 | delete $AnyEvent::MP::Base::WKP{ $self->{wkname} }; |
306 | delete $AnyEvent::MP::Base::WKP{ $self->{wkname} }; |
268 | |
307 | |
269 | delete $AnyEvent::MP::Base::PORT{$_} |
308 | delete $AnyEvent::MP::Base::PORT{$_} |
270 | for @{ $self->{names} }; |
309 | for @{ $self->{names} }; |
271 | } |
310 | } |