… | |
… | |
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 | become_slave become_public |
92 | become_slave become_public |
92 | ); |
93 | ); |
93 | |
94 | |
94 | =item NODE / $NODE |
95 | =item NODE / $NODE |
95 | |
96 | |
… | |
… | |
117 | 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 |
118 | 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 |
119 | 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 |
120 | node, anything can be passed. |
121 | node, anything can be passed. |
121 | |
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 | |
122 | =item $local_port = create_port |
145 | =item $local_port = create_port |
123 | |
146 | |
124 | 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. |
125 | |
148 | |
126 | =cut |
149 | =cut |
127 | |
150 | |
128 | sub create_port { |
151 | sub create_port { |
129 | my $id = "$AnyEvent::MP::Base::UNIQ." . ++$AnyEvent::MP::Base::ID; |
152 | my $id = "$AnyEvent::MP::Base::UNIQ." . $AnyEvent::MP::Base::ID++; |
130 | |
153 | |
131 | my $self = bless { |
154 | my $self = bless { |
132 | id => "$NODE#$id", |
155 | id => "$NODE#$id", |
133 | names => [$id], |
156 | names => [$id], |
134 | }, "AnyEvent::MP::Port"; |
157 | }, "AnyEvent::MP::Port"; |
… | |
… | |
155 | }; |
178 | }; |
156 | |
179 | |
157 | $self |
180 | $self |
158 | } |
181 | } |
159 | |
182 | |
|
|
183 | =item $portid = miniport { my @msg = @_; $finished } |
|
|
184 | |
|
|
185 | Creates a "mini port", that is, a very lightweight port without any |
|
|
186 | pattern matching behind it, and returns its ID. |
|
|
187 | |
|
|
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. |
|
|
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 | |
|
|
203 | sub miniport(&) { |
|
|
204 | my $cb = shift; |
|
|
205 | my $id = "$AnyEvent::MP::Base::UNIQ." . $AnyEvent::MP::Base::ID++; |
|
|
206 | |
|
|
207 | $AnyEvent::MP::Base::PORT{$id} = sub { |
|
|
208 | &$cb |
|
|
209 | and del $id; |
|
|
210 | }; |
|
|
211 | |
|
|
212 | "$NODE#$id" |
|
|
213 | } |
|
|
214 | |
160 | package AnyEvent::MP::Port; |
215 | package AnyEvent::MP::Port; |
161 | |
216 | |
162 | =back |
217 | =back |
163 | |
218 | |
164 | =head1 METHODS FOR PORT OBJECTS |
219 | =head1 METHODS FOR PORT OBJECTS |
… | |
… | |
173 | =cut |
228 | =cut |
174 | |
229 | |
175 | use overload |
230 | use overload |
176 | '""' => sub { $_[0]{id} }, |
231 | '""' => sub { $_[0]{id} }, |
177 | fallback => 1; |
232 | fallback => 1; |
|
|
233 | |
|
|
234 | sub TO_JSON { $_[0]{id} } |
178 | |
235 | |
179 | =item $port->rcv (type => $callback->($port, @msg)) |
236 | =item $port->rcv (type => $callback->($port, @msg)) |
180 | |
237 | |
181 | =item $port->rcv ($smartmatch => $callback->($port, @msg)) |
238 | =item $port->rcv ($smartmatch => $callback->($port, @msg)) |
182 | |
239 | |
… | |
… | |
242 | =cut |
299 | =cut |
243 | |
300 | |
244 | sub destroy { |
301 | sub destroy { |
245 | my ($self) = @_; |
302 | my ($self) = @_; |
246 | |
303 | |
|
|
304 | AnyEvent::MP::Base::del $self->{id}; |
|
|
305 | |
247 | delete $AnyEvent::MP::Base::WKP{ $self->{wkname} }; |
306 | delete $AnyEvent::MP::Base::WKP{ $self->{wkname} }; |
248 | |
307 | |
249 | delete $AnyEvent::MP::Base::PORT{$_} |
308 | delete $AnyEvent::MP::Base::PORT{$_} |
250 | for @{ $self->{names} }; |
309 | for @{ $self->{names} }; |
251 | } |
310 | } |