slave 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,117 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Class: o</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <h1>o <sup class="type-note">(Class)</sup></h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>In:</strong></td>
54
+ <td>
55
+ <a href="../files/lib/slave_rb.html">
56
+ lib/slave.rb
57
+ </a>
58
+ <br />
59
+ </td>
60
+ </tr>
61
+
62
+ </table>
63
+ </div>
64
+ <!-- banner header -->
65
+
66
+ <div id="bodyContent">
67
+
68
+
69
+ <div id="contextContent">
70
+ <div id="diagram">
71
+ <map name="map">
72
+ <area shape="RECT" coords="123,98,195,50" href="o.html" alt="o">
73
+ <area shape="RECT" coords="27,98,99,50" href="Slave.html" alt="Slave">
74
+ </map>
75
+ <img src="../dot/f_1.jpg" usemap="#map" border=0 alt="TopLevel">
76
+ </div>
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+ <div id="attribute-list">
85
+ <h2 class="section-bar">Attributes</h2>
86
+
87
+ <div class="name-list">
88
+ <table>
89
+ <tr class="top-aligned-row context-row">
90
+ <td class="context-item-name">__slave_object_failure__</td>
91
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
92
+ <td class="context-item-desc"></td>
93
+ </tr>
94
+ </table>
95
+ </div>
96
+ </div>
97
+
98
+
99
+ </div>
100
+
101
+
102
+
103
+ <!-- if includes -->
104
+
105
+
106
+ <!-- if method_list -->
107
+
108
+
109
+ </div>
110
+
111
+
112
+ <div id="validator-badges">
113
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
114
+ </div>
115
+
116
+ </body>
117
+ </html>
@@ -0,0 +1,117 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Class: object</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <h1>object <sup class="type-note">(Class)</sup></h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>In:</strong></td>
54
+ <td>
55
+ <a href="../files/lib/slave_rb.html">
56
+ lib/slave.rb
57
+ </a>
58
+ <br />
59
+ </td>
60
+ </tr>
61
+
62
+ </table>
63
+ </div>
64
+ <!-- banner header -->
65
+
66
+ <div id="bodyContent">
67
+
68
+
69
+ <div id="contextContent">
70
+ <div id="diagram">
71
+ <map name="map">
72
+ <area shape="RECT" coords="123,98,195,50" href="Slave.html" alt="Slave">
73
+ <area shape="RECT" coords="27,98,99,50" href="object.html" alt="object">
74
+ </map>
75
+ <img src="../dot/f_1.jpg" usemap="#map" border=0 alt="TopLevel">
76
+ </div>
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+ <div id="attribute-list">
85
+ <h2 class="section-bar">Attributes</h2>
86
+
87
+ <div class="name-list">
88
+ <table>
89
+ <tr class="top-aligned-row context-row">
90
+ <td class="context-item-name">__slave_object_failure__</td>
91
+ <td class="context-item-value">&nbsp;[RW]&nbsp;</td>
92
+ <td class="context-item-desc"></td>
93
+ </tr>
94
+ </table>
95
+ </div>
96
+ </div>
97
+
98
+
99
+ </div>
100
+
101
+
102
+
103
+ <!-- if includes -->
104
+
105
+
106
+ <!-- if method_list -->
107
+
108
+
109
+ </div>
110
+
111
+
112
+ <div id="validator-badges">
113
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
114
+ </div>
115
+
116
+ </body>
117
+ </html>
data/doc/created.rid CHANGED
@@ -1 +1 @@
1
- Thu Jun 08 15:55:38 MDT 2006
1
+ Fri Oct 13 13:24:48 MDT 2006
data/doc/dot/f_0.jpg CHANGED
Binary file
data/doc/dot/f_1.dot CHANGED
@@ -14,6 +14,15 @@ digraph TopLevel {
14
14
  fontname = Arial
15
15
  color = red
16
16
  label = "lib/slave.rb"
17
+ o [
18
+ fontcolor = black,
19
+ URL = "classes/o.html",
20
+ shape = ellipse,
21
+ color = palegoldenrod,
22
+ style = filled,
23
+ label = "o"
24
+ ]
25
+
17
26
  Slave [
18
27
  fontcolor = black,
19
28
  URL = "classes/Slave.html",
data/doc/dot/f_1.jpg CHANGED
Binary file
@@ -56,7 +56,7 @@
56
56
  </tr>
57
57
  <tr class="top-aligned-row">
58
58
  <td><strong>Last Update:</strong></td>
59
- <td>Thu Jun 08 14:54:53 MDT 2006</td>
59
+ <td>Fri Oct 13 13:23:22 MDT 2006</td>
60
60
  </tr>
61
61
  </table>
62
62
  </div>
@@ -74,70 +74,225 @@
74
74
 
75
75
  <div id="description">
76
76
  <p>
77
- the <a href="../classes/Slave.html">Slave</a> class forks a process and
78
- starts a drb server in the child using any object as the server. the
79
- process is detached so it is not required (nor possible) to wait on the
80
- child pid. a Heartbeat is set up between the parent and child processes so
81
- that the child will exit of the parent exits for any reason - preventing
82
- orphaned slaves from running indefinitely. the purpose of Slaves is to be
83
- able to easily set up a collection of objects communicating via drb
84
- protocols instead of having to use IPC.
85
- </p>
86
- <p>
87
- typical usage:
77
+ SYNOPSIS
88
78
  </p>
89
79
  <pre>
90
- obj = AnyClass::new
80
+ the Slave class forks a process and starts a drb server in the child using
81
+ any object as the server. the process is detached so it is not required
82
+ (nor possible) to wait on the child pid. a Heartbeat is set up between the
83
+ parent and child processes so that the child will exit of the parent exits
84
+ for any reason - preventing orphaned slaves from running indefinitely. the
85
+ purpose of Slaves is to be able to easily set up a collection of objects
86
+ communicating via drb protocols instead of having to use IPC.
87
+
88
+ typical usage:
89
+
90
+ obj = AnyClass::new
91
+
92
+ slave = Slave::new 'object' =&gt; obj
93
+
94
+ p slave.object # handle on drb object
95
+ p slave.uri # uri of the drb object
96
+ p slave.socket # unix domain socket path for drb object
97
+ p slave.psname # title shown in ps/top
91
98
 
92
- slave = Slave::new obj
99
+ slaves may be configured via the environment, the Slave class, or via the
100
+ ctor for object itself. attributes which may be configured include
93
101
 
94
- p slave.object # handle on drb object
95
- p slave.uri # uri of the drb object
96
- p slave.socket # unix domain socket path for drb object
97
- p slave.psname # title shown in ps/top
102
+ * socket_creation_attempts
103
+ * pulse_rate
104
+ * psname
105
+ * debug
106
+ * dumped
98
107
  </pre>
99
108
  <p>
100
- other usage:
101
- </p>
102
- <p>
103
- set the pulse_rate used for the Heartbeat
109
+ URIS
104
110
  </p>
105
111
  <pre>
106
- slave = Slave::new MyClass::new, 'pulse_rate' =&gt; 10
112
+ http://rubyforge.org/projects/codeforpeople/
113
+ http://codeforpeople.com/lib/ruby/slave
107
114
  </pre>
108
115
  <p>
109
- same
116
+ HISTORY
110
117
  </p>
111
118
  <pre>
112
- Slave::pulse_rate = 10
113
- slave = Slave::new MyClass::new
119
+ THIS RELEASE IS !! NOT !! BACKWARD COMPATIBLE. NOTE NEW CTOR SYNTAX.
120
+
121
+ 1.0.0:
122
+
123
+ - detach method also sets up at_exit handler. extra protection from
124
+ zombies.
125
+
126
+ - ezra zygmuntowicz asked for a feature whereby a parent could be notified
127
+ when a child exited. obviously such a mechanism should be both async
128
+ and sync. to accomplish this the wait method was extended to support a
129
+ callback with is either sync or async
130
+
131
+ slave = Server.new{ Server.new }
132
+
133
+ slave.wait and puts 'this is sync!'
134
+
135
+ slave.wait(:non_block=&gt;true){ 'this is async!' }
136
+
137
+ - patch to getval from skaar&lt;skaar@waste.org&gt;. the impl dropped opts
138
+ delgating to the class method from the instance one.
139
+
140
+ 0.2.0:
141
+ incorporated joel vanderWerf's patch such that, if no object is passed the
142
+ block is used to create one ONLY in the child. this avoids having a copy
143
+ in both parent and child is that needs to be avoided due to, for instance,
144
+ resource consumption.
145
+
146
+ 0.0.1:
147
+ - patch from Logan Capaldo adds block form to slave new, block is run in the
148
+ child
149
+
150
+ - added a few more samples/*
151
+
152
+ - added Slave#wait
153
+
154
+ - added status information to slaves
155
+
156
+ - added close-on-exec flag to pipes in parent process
157
+
158
+ 0.0.0:
159
+ - initial version
114
160
  </pre>
115
161
  <p>
116
- same
162
+ SAMPLES
117
163
  </p>
118
164
  <pre>
119
- ENV['SLAVE_PULSE_RATE'] = 10
120
- slave = Slave::new MyClass::new
121
- </pre>
122
- <p>
123
- slaves may be configured via the environment, the <a
124
- href="../classes/Slave.html">Slave</a> class, or via the ctor for object
125
- itself. attributes which may be configured include
126
- </p>
127
- <ul>
128
- <li>socket_creation_attempts
165
+ &lt;========&lt; samples/a.rb &gt;========&gt;
166
+
167
+ ~ &gt; cat samples/a.rb
168
+
169
+ require 'slave'
170
+ #
171
+ # simple usage is simply to stand up a server object as a slave. you do not
172
+ # need to wait for the server, join it, etc. it will die when the parent
173
+ # process dies - even under 'kill -9' conditions
174
+ #
175
+ class Server
176
+ def add_two n
177
+ n + 2
178
+ end
179
+ end
180
+
181
+ slave = Slave.new :object =&gt; Server.new
182
+ server = slave.object
183
+
184
+ p server.add_two(40) #=&gt; 42
185
+
186
+ ~ &gt; ruby samples/a.rb
187
+
188
+ 42
189
+
190
+ &lt;========&lt; samples/b.rb &gt;========&gt;
191
+
192
+ ~ &gt; cat samples/b.rb
193
+
194
+ require 'slave'
195
+ #
196
+ # if certain operations need to take place in the child only a block can be
197
+ # used
198
+ #
199
+ class Server
200
+ def connect_to_db
201
+ &quot;we only want to do this in the child process!&quot;
202
+ @connection = :postgresql
203
+ end
204
+ attr :connection
205
+ end
206
+
207
+ slave = Slave.new('object' =&gt; Server.new){|s| s.connect_to_db}
208
+
209
+ server = slave.object
210
+
211
+ p server.connection #=&gt; :postgresql
212
+ #
213
+ # errors in the child are detected and raised in the parent
214
+ #
215
+ slave = Slave.new('object' =&gt; Server.new){|s| s.typo} #=&gt; raises an error!
216
+
217
+ ~ &gt; ruby samples/b.rb
218
+
219
+ :postgresql
220
+ ./lib/slave.rb:276:in `initialize': undefined method `typo' for #&lt;Server:0xb7573350&gt; (NoMethodError)
221
+ from samples/b.rb:22:in `new'
222
+ from samples/b.rb:22
223
+
224
+ &lt;========&lt; samples/c.rb &gt;========&gt;
129
225
 
130
- </li>
131
- <li>pulse_rate
226
+ ~ &gt; cat samples/c.rb
132
227
 
133
- </li>
134
- <li>psname
228
+ require 'slave'
229
+ #
230
+ # if no slave object is given the block itself is used to contruct it
231
+ #
232
+ class Server
233
+ def initialize
234
+ &quot;this is run only in the child&quot;
235
+ @pid = Process.pid
236
+ end
237
+ attr 'pid'
238
+ end
135
239
 
136
- </li>
137
- <li>debug
240
+ slave = Slave.new{ Server.new }
241
+ server = slave.object
138
242
 
139
- </li>
140
- </ul>
243
+ p Process.pid
244
+ p server.pid # not going to be the same as parents!
245
+ #
246
+ # errors are still detected though
247
+ #
248
+ slave = Slave.new{ fubar } # raises error in parent
249
+
250
+ ~ &gt; ruby samples/c.rb
251
+
252
+ 12244
253
+ 12245
254
+ ./lib/slave.rb:276:in `initialize': undefined local variable or method `fubar' for main:Object (NameError)
255
+ from samples/c.rb:21:in `new'
256
+ from samples/c.rb:21
257
+
258
+ &lt;========&lt; samples/d.rb &gt;========&gt;
259
+
260
+ ~ &gt; cat samples/d.rb
261
+
262
+ require 'slave'
263
+ #
264
+ # at_exit hanlders are handled correctly in both child and parent
265
+ #
266
+ at_exit{ p 'parent' }
267
+ slave = Slave.new{ at_exit{ p 'child' }; 'the server is this string' }
268
+ #
269
+ # this will print 'child', then 'parent'
270
+ #
271
+
272
+ ~ &gt; ruby samples/d.rb
273
+
274
+ &quot;parent&quot;
275
+
276
+ &lt;========&lt; samples/e.rb &gt;========&gt;
277
+
278
+ ~ &gt; cat samples/e.rb
279
+
280
+ require 'slave'
281
+ #
282
+ # slaves never outlive their parent. if the parent exits, even under kill -9,
283
+ # the child will die.
284
+ #
285
+ slave = Slave.new{ at_exit{ p 'child' }; 'the server is this string' }
286
+
287
+ Process.kill brutal=9, the_parent_pid=Process.pid
288
+ #
289
+ # even though parent dies a nasty death the child will still print 'child'
290
+ #
291
+
292
+ ~ &gt; ruby samples/e.rb
293
+
294
+ &quot;child&quot;
295
+ </pre>
141
296
 
142
297
  </div>
143
298