slave 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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