ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-Fork-Remote/README
Revision: 1.2
Committed: Sun Apr 28 15:36:30 2013 UTC (11 years ago) by root
Branch: MAIN
CVS Tags: rel-1_0, rel-0_2, HEAD
Changes since 1.1: +253 -0 lines
Log Message:
0.2

File Contents

# Content
1 NAME
2 AnyEvent::Fork::Remote - remote processes with AnyEvent::Fork interface
3
4 THE API IS NOT FINISHED, CONSIDER THIS A BETA RELEASE
5
6 SYNOPSIS
7 use AnyEvent;
8 use AnyEvent::Fork::Remote;
9
10 my $rpc = AnyEvent::Fork::Remote
11 ->new_execp ("ssh", "ssh", "othermachine", "perl")
12 ->require ("MyModule")
13 ->run ("MyModule::run", my $cv = AE::cv);
14
15 my $fh = $cv->recv;
16
17 DESCRIPTION
18 Despite what the name of this module might suggest, it doesn't actually
19 create remote processes for you. But it does make it easy to use them,
20 once you have started them.
21
22 This module implements a very similar API as AnyEvent::Fork. In fact,
23 similar enough to require at most minor modifications to support both at
24 the same time. For example, it works with AnyEvent::Fork::RPC and
25 AnyEvent::Fork::Pool.
26
27 The documentation for this module will therefore only document the parts
28 of the API that differ between the two modules.
29
30 SUMMARY OF DIFFERENCES
31 Here is a short summary of the main differences between AnyEvent::Fork
32 and this module:
33
34 * "send_fh" is not implemented and will fail
35
36 * the child-side "run" function must read from STDIN and write to
37 STDOUT
38
39 * "fork" does not actually fork, but will create a new process
40
41 EXAMPLE
42 This example uses a local perl (because that is likely going to work
43 without further setup) and the AnyEvent::Fork::RPC to create simple
44 worker process.
45
46 First load the modules we are going to use:
47
48 use AnyEvent;
49 use AnyEvent::Fork::Remote;
50 use AnyEvent::Fork::RPC;
51
52 Then create, configure and run the process:
53
54 my $rpc = AnyEvent::Fork::Remote
55 ->new_execp ("perl", "perl")
56 ->eval ('
57 sub myrun {
58 "this is process $$, and you passed <@_>"
59 }
60 ')
61 ->AnyEvent::Fork::RPC::run ("myrun");
62
63 We use "new_execp" to execute the first perl found in the PATH. You'll
64 have to make sure there is one for this to work. The perl does not
65 actually have to be the same perl as the one running the example, and it
66 doesn't need to have any modules installed.
67
68 The reason we have to specif< "perl" twice is that the first argument to
69 "new_execp" (and also "new_exec") is the program name or path, while the
70 remaining ones are the arguments, and the first argument passed to a
71 program is the program name, so it has to be specified twice.
72
73 Finally, the standard example, send some numbers to the remote function,
74 and print whatever it returns:
75
76 my $cv = AE::cv;
77
78 for (1..10) {
79 $cv->begin;
80 $rpc->($_, sub {
81 print "remote function returned: $_[0]\n";
82 $cv->end;
83 });
84 }
85
86 $cv->recv;
87
88 Now, executing perl in the PATH isn't very interesting - you could have
89 done the same with AnyEvent::Fork, and it might even be more efficient.
90
91 The power of this module is that the perl doesn't need to run on the
92 local box, you could simply substitute another command, such as ssh
93 remotebox perl:
94
95 my $rpc = AnyEvent::Fork::Remote
96 ->new_execp ("ssh", "ssh", "remotebox", "perl")
97
98 And if you want to use a specific path for ssh, use "new_exec":
99
100 my $rpc = AnyEvent::Fork::Remote
101 ->new_exec ("/usr/bin/ssh", "ssh", "remotebox", "perl")
102
103 Of course, it doesn't really matter to this module how you construct
104 your perl processes, what matters is that somehow, you give it a file
105 handle connected to the new perls STDIN and STDOUT.
106
107 PARENT PROCESS USAGE
108 my $proc = new_exec AnyEvent::Fork::Remote $path, @args...
109 Creates a new "AnyEvent::Fork::Remote" object. Unlike
110 AnyEvent::Fork, processes are only created when "run" is called,
111 every other method call is is simply recorded until then.
112
113 Each time a new process is needed, it executes $path with the given
114 arguments (the first array member must be the program name, as with
115 the "exec" function with explicit PROGRAM argument) and both "STDIN"
116 and "STDOUT" connected to a communications socket. No input must be
117 consumed by the command before perl is started, and no output should
118 be generated.
119
120 The program *must* invoke perl somehow, with STDIN and STDOUT
121 intact, without specifying anything to execute (no script file name,
122 no "-e" switch etc.).
123
124 Here are some examples to give you an idea:
125
126 # just "perl"
127 $proc = new_exec AnyEvent::Fork::Remote
128 "/usr/bin/perl", "perl";
129
130 # rsh othernode exec perl
131 $proc = new_exec AnyEvent::Fork::Remote
132 "/usr/bin/rsh", "rsh", "othernode", "exec perl";
133
134 # a complicated ssh command
135 $proc = new_exec AnyEvent::Fork::Remote
136 "/usr/bin/ssh",
137 qw(ssh -q
138 -oCheckHostIP=no -oTCPKeepAlive=yes -oStrictHostKeyChecking=no
139 -oGlobalKnownHostsFile=/dev/null -oUserKnownHostsFile=/dev/null
140 otherhost
141 exec perl);
142
143 my $proc = new_execp AnyEvent::Fork::Remote $file, @args...
144 Just like "new_exec", except that the program is searched in the
145 $ENV{PATH} first, similarly to how the shell does it. This makes it
146 easier to find e.g. "ssh":
147
148 $proc = new_execp AnyEvent::Fork::Remote "ssh", "ssh", "otherhost", "perl";
149
150 my $proc = new AnyEvent::Fork::Remote $create_callback
151 Basically the same as "new_exec", but instead of a command to
152 execute, it expects a callback which is invoked each time a process
153 needs to be created.
154
155 The $create_callback is called with another callback as argument,
156 and should call this callback with the file handle that is connected
157 to a perl process. This callback can be invoked even after the
158 $create_callback returns.
159
160 Example: emulate "new_exec" using "new".
161
162 use AnyEvent::Util;
163 use Proc::FastSpawn;
164
165 $proc = new AnyEvent::Fork::Remote sub {
166 my $done = shift;
167
168 my ($a, $b) = AnyEvent::Util::portable_socketpair
169 or die;
170
171 open my $oldin , "<&0" or die;
172 open my $oldout, ">&1" or die;
173
174 open STDIN , "<&" . fileno $b or die;
175 open STDOUT, ">&" . fileno $b or die;
176
177 spawn "/usr/bin/rsh", ["rsh", "othernode", "perl"];
178
179 open STDIN , "<&" . fileno $oldin ;
180 open STDOUT, ">&" . fileno $oldout;
181
182 $done->($a);
183 };
184
185 my $proc = new_from_fh $fh
186 Creates an "AnyEvent::Fork::Remote" object from a file handle. This
187 file handle must be connected to both STDIN and STDOUT of a perl
188 process.
189
190 This form might be more convenient than "new" or "new_exec" when
191 creating an "AnyEvent::Fork::Remote" object, but the resulting
192 object does not support "fork".
193
194 $new_proc = $proc->fork
195 Quite the same as the same method of AnyEvent::Fork, except that it
196 simply clones the object without creating an actual process.
197
198 undef = $proc->pid
199 The "pid" method always returns "undef" and only exists for
200 compatibility with AnyEvent::Fork.
201
202 $proc = $proc->send_fh (...)
203 Not supported and always croaks.
204
205 $proc = $proc->eval ($perlcode, @args)
206 Quite the same as the same method of AnyEvent::Fork.
207
208 $proc = $proc->require ($module, ...)
209 Quite the same as the same method of AnyEvent::Fork.
210
211 $proc = $proc->send_arg ($string, ...)
212 Quite the same as the same method of AnyEvent::Fork.
213
214 $proc->run ($func, $cb->($fh))
215 Very similar to the run method of AnyEvent::Fork.
216
217 On the parent side, the API is identical, except that a $cb argument
218 of "undef" instead of a valid file handle signals an error.
219
220 On the child side, the "communications socket" is in fact just
221 *STDIN, and typically can only be read from (this highly depends on
222 how the program is created - if you just run perl locally, it will
223 work for both reading and writing, but commands such as rsh or ssh
224 typically only provide read-only handles for STDIN).
225
226 To be portable, if the run function wants to read data that is
227 written to $fh in the parent, then it should read from STDIN. If the
228 run function wants to provide data that can later be read from $fh,
229 then it should write them to STDOUT.
230
231 You can write a run function that works with both AnyEvent::Fork and
232 this module by checking "fileno $fh". If it is 0 (meaning it is
233 STDIN), then you should use it for reading, and STDOUT for writing.
234 Otherwise, you should use the file handle for both:
235
236 sub run {
237 my ($rfh, ...) = @_;
238 my $wfh = fileno $rfh ? $rfh : *STDOUT;
239
240 # now use $rfh for reading and $wfh for writing
241 }
242
243 SEE ALSO
244 AnyEvent::Fork, the same as this module, for local processes.
245
246 AnyEvent::Fork::RPC, to talk to the created processes.
247
248 AnyEvent::Fork::Pool, to manage whole pools of processes.
249
250 AUTHOR AND CONTACT INFORMATION
251 Marc Lehmann <schmorp@schmorp.de>
252 http://software.schmorp.de/pkg/AnyEvent-Fork-Remote
253