1IO::Async::Function(3)User Contributed Perl DocumentationIO::Async::Function(3)
2
3
4
6 "IO::Async::Function" - call a function asynchronously
7
9 use IO::Async::Function;
10
11 use IO::Async::Loop;
12 my $loop = IO::Async::Loop->new;
13
14 my $function = IO::Async::Function->new(
15 code => sub {
16 my ( $number ) = @_;
17 return is_prime( $number );
18 },
19 );
20
21 $loop->add( $function );
22
23 $function->call(
24 args => [ 123454321 ],
25 )->on_done( sub {
26 my $isprime = shift;
27 print "123454321 " . ( $isprime ? "is" : "is not" ) . " a prime number\n";
28 })->on_fail( sub {
29 print STDERR "Cannot determine if it's prime - $_[0]\n";
30 })->get;
31
33 This subclass of IO::Async::Notifier wraps a function body in a
34 collection of worker processes, to allow it to execute independently of
35 the main process. The object acts as a proxy to the function, allowing
36 invocations to be made by passing in arguments, and invoking a
37 continuation in the main process when the function returns.
38
39 The object represents the function code itself, rather than one
40 specific invocation of it. It can be called multiple times, by the
41 "call" method. Multiple outstanding invocations can be called; they
42 will be dispatched in the order they were queued. If only one worker
43 process is used then results will be returned in the order they were
44 called. If multiple are used, then each request will be sent in the
45 order called, but timing differences between each worker may mean
46 results are returned in a different order.
47
48 Since the code block will be called multiple times within the same
49 child process, it must take care not to modify any of its state that
50 might affect subsequent calls. Since it executes in a child process, it
51 cannot make any modifications to the state of the parent program.
52 Therefore, all the data required to perform its task must be
53 represented in the call arguments, and all of the result must be
54 represented in the return values.
55
56 The Function object is implemented using an IO::Async::Routine with two
57 IO::Async::Channel objects to pass calls into and results out from it.
58
59 The IO::Async framework generally provides mechanisms for multiplexing
60 IO tasks between different handles, so there aren't many occasions when
61 such an asynchronous function is necessary. Two cases where this does
62 become useful are:
63
64 1. When a large amount of computationally-intensive work needs to be
65 performed (for example, the "is_prime" test in the example in the
66 "SYNOPSIS").
67
68 2. When a blocking OS syscall or library-level function needs to be
69 called, and no nonblocking or asynchronous version is supplied.
70 This is used by IO::Async::Resolver.
71
72 This object is ideal for representing "pure" functions; that is, blocks
73 of code which have no stateful effect on the process, and whose result
74 depends only on the arguments passed in. For a more general co-routine
75 ability, see also IO::Async::Routine.
76
78 The following named parameters may be passed to "new" or "configure":
79
80 code => CODE
81 The body of the function to execute.
82
83 @result = $code->( @args )
84
85 init_code => CODE
86 Optional. If defined, this is invoked exactly once in every child
87 process or thread, after it is created, but before the first invocation
88 of the function body itself.
89
90 $init_code->()
91
92 module => STRING
93 func => STRING
94 An alternative to the "code" argument, which names a module to load and
95 a function to call within it. "module" should give a perl module name
96 (i.e. "Some::Name", not a filename like Some/Name.pm), and "func"
97 should give the basename of a function within that module (i.e. without
98 the module name prefixed). It will be invoked, without extra arguments,
99 as the main code body of the object.
100
101 The task of loading this module and resolving the resulting function
102 from it is only performed on the remote worker side, so the controlling
103 process will not need to actually load the module.
104
105 init_func => STRING or ARRAY [ STRING, ... ]
106 Optional addition to the "module" and "func" alternatives. Names a
107 function within the module to call each time a new worker is created.
108
109 If this value is an array reference, its first element must be a string
110 giving the name of the function; the remaining values are passed to
111 that function as arguments.
112
113 model => "fork" | "thread" | "spawn"
114 Optional. Requests a specific IO::Async::Routine model. If not
115 supplied, leaves the default choice up to Routine.
116
117 min_workers => INT
118 max_workers => INT
119 The lower and upper bounds of worker processes to try to keep running.
120 The actual number running at any time will be kept somewhere between
121 these bounds according to load.
122
123 max_worker_calls => INT
124 Optional. If provided, stop a worker process after it has processed
125 this number of calls. (New workers may be started to replace stopped
126 ones, within the bounds given above).
127
128 idle_timeout => NUM
129 Optional. If provided, idle worker processes will be shut down after
130 this amount of time, if there are more than "min_workers" of them.
131
132 exit_on_die => BOOL
133 Optional boolean, controls what happens after the "code" throws an
134 exception. If missing or false, the worker will continue running to
135 process more requests. If true, the worker will be shut down. A new
136 worker might be constructed by the "call" method to replace it, if
137 necessary.
138
139 setup => ARRAY
140 Optional array reference. Specifies the "setup" key to pass to the
141 underlying IO::Async::Process when setting up new worker processes.
142
144 The following methods documented with a trailing call to "->get" return
145 Future instances.
146
147 start
148 $function->start
149
150 Start the worker processes
151
152 stop
153 $function->stop
154
155 Stop the worker processes
156
157 $f = $function->stop
158
159 Since version 0.75.
160
161 If called in non-void context, returns a IO::Async::Future instance
162 that will complete once every worker process has stopped and exited.
163 This may be useful for waiting until all of the processes are waited
164 on, or other edge-cases, but is not otherwise particularly useful.
165
166 restart
167 $function->restart
168
169 Gracefully stop and restart all the worker processes.
170
171 call
172 @result = $function->call( %params )->get
173
174 Schedules an invocation of the contained function to be executed on one
175 of the worker processes. If a non-busy worker is available now, it will
176 be called immediately. If not, it will be queued and sent to the next
177 free worker that becomes available.
178
179 The request will already have been serialised by the marshaller, so it
180 will be safe to modify any referenced data structures in the arguments
181 after this call returns.
182
183 The %params hash takes the following keys:
184
185 args => ARRAY
186 A reference to the array of arguments to pass to the code.
187
188 priority => NUM
189 Optional. Defines the sorting order when no workers are
190 available and calls must be queued for later. A default of zero
191 will apply if not provided.
192
193 Higher values cause the call to be considered more important,
194 and will be placed earlier in the queue than calls with a
195 smaller value. Calls of equal priority are still handled in
196 FIFO order.
197
198 If the function body returns normally the list of results are provided
199 as the (successful) result of returned future. If the function throws
200 an exception this results in a failed future. In the special case that
201 the exception is in fact an unblessed "ARRAY" reference, this array is
202 unpacked and used as-is for the "fail" result. If the exception is not
203 such a reference, it is used as the first argument to "fail", in the
204 category of "error".
205
206 $f->done( @result )
207
208 $f->fail( @{ $exception } )
209 $f->fail( $exception, error => )
210
211 call (void)
212 $function->call( %params )
213
214 When not returning a future, the "on_result", "on_return" and
215 "on_error" arguments give continuations to handle successful results or
216 failure.
217
218 on_result => CODE
219 A continuation that is invoked when the code has been executed.
220 If the code returned normally, it is called as:
221
222 $on_result->( 'return', @values )
223
224 If the code threw an exception, or some other error occurred
225 such as a closed connection or the process died, it is called
226 as:
227
228 $on_result->( 'error', $exception_name )
229
230 on_return => CODE and on_error => CODE
231 An alternative to "on_result". Two continuations to use in
232 either of the circumstances given above. They will be called
233 directly, without the leading 'return' or 'error' value.
234
235 workers
236 $count = $function->workers
237
238 Returns the total number of worker processes available
239
240 workers_busy
241 $count = $function->workers_busy
242
243 Returns the number of worker processes that are currently busy
244
245 workers_idle
246 $count = $function->workers_idle
247
248 Returns the number of worker processes that are currently idle
249
251 Extended Error Information on Failure
252 The array-unpacking form of exception indiciation allows the function
253 body to more precicely control the resulting failure from the "call"
254 future.
255
256 my $divider = IO::Async::Function->new(
257 code => sub {
258 my ( $numerator, $divisor ) = @_;
259 $divisor == 0 and
260 die [ "Cannot divide by zero", div_zero => $numerator, $divisor ];
261
262 return $numerator / $divisor;
263 }
264 );
265
267 For the record, 123454321 is 11111 * 11111, a square number, and
268 therefore not prime.
269
271 Paul Evans <leonerd@leonerd.org.uk>
272
273
274
275perl v5.34.0 2021-08-08 IO::Async::Function(3)