slave 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +164 -26
- data/README.tmpl +83 -0
- data/doc/classes/(@object = Object.new).html +117 -0
- data/doc/classes/(o = Object.new).html +117 -0
- data/doc/classes/@object.html +117 -0
- data/doc/classes/Slave.html +458 -225
- data/doc/classes/Slave/Heartbeat.html +200 -199
- data/doc/classes/o.html +117 -0
- data/doc/classes/object.html +117 -0
- data/doc/created.rid +1 -1
- data/doc/dot/f_0.jpg +0 -0
- data/doc/dot/f_1.dot +9 -0
- data/doc/dot/f_1.jpg +0 -0
- data/doc/files/README.html +200 -45
- data/doc/files/lib/slave_rb.html +4 -2
- data/doc/fr_class_index.html +1 -0
- data/doc/fr_method_index.html +23 -19
- data/gen_readme.rb +32 -0
- data/lib/{slave-0.2.0.rb → slave-1.0.0.rb} +185 -60
- data/lib/slave.rb +185 -60
- data/{sample → samples}/a.rb +7 -10
- data/samples/b.rb +22 -0
- data/samples/c.rb +21 -0
- data/samples/d.rb +9 -0
- data/samples/e.rb +11 -0
- data/slave-1.0.0.gem +0 -0
- data/test.old/slave.rb +21 -0
- metadata +19 -7
- data/sample/b.rb +0 -8
- data/sample/c.rb +0 -109
data/doc/classes/o.html
ADDED
@@ -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"> [RW] </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"> [RW] </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
|
-
|
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
|
data/doc/files/README.html
CHANGED
@@ -56,7 +56,7 @@
|
|
56
56
|
</tr>
|
57
57
|
<tr class="top-aligned-row">
|
58
58
|
<td><strong>Last Update:</strong></td>
|
59
|
-
<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
|
-
|
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
|
-
|
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' => 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
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
102
|
+
* socket_creation_attempts
|
103
|
+
* pulse_rate
|
104
|
+
* psname
|
105
|
+
* debug
|
106
|
+
* dumped
|
98
107
|
</pre>
|
99
108
|
<p>
|
100
|
-
|
101
|
-
</p>
|
102
|
-
<p>
|
103
|
-
set the pulse_rate used for the Heartbeat
|
109
|
+
URIS
|
104
110
|
</p>
|
105
111
|
<pre>
|
106
|
-
|
112
|
+
http://rubyforge.org/projects/codeforpeople/
|
113
|
+
http://codeforpeople.com/lib/ruby/slave
|
107
114
|
</pre>
|
108
115
|
<p>
|
109
|
-
|
116
|
+
HISTORY
|
110
117
|
</p>
|
111
118
|
<pre>
|
112
|
-
|
113
|
-
|
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=>true){ 'this is async!' }
|
136
|
+
|
137
|
+
- patch to getval from skaar<skaar@waste.org>. 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
|
-
|
162
|
+
SAMPLES
|
117
163
|
</p>
|
118
164
|
<pre>
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
165
|
+
<========< samples/a.rb >========>
|
166
|
+
|
167
|
+
~ > 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 => Server.new
|
182
|
+
server = slave.object
|
183
|
+
|
184
|
+
p server.add_two(40) #=> 42
|
185
|
+
|
186
|
+
~ > ruby samples/a.rb
|
187
|
+
|
188
|
+
42
|
189
|
+
|
190
|
+
<========< samples/b.rb >========>
|
191
|
+
|
192
|
+
~ > 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
|
+
"we only want to do this in the child process!"
|
202
|
+
@connection = :postgresql
|
203
|
+
end
|
204
|
+
attr :connection
|
205
|
+
end
|
206
|
+
|
207
|
+
slave = Slave.new('object' => Server.new){|s| s.connect_to_db}
|
208
|
+
|
209
|
+
server = slave.object
|
210
|
+
|
211
|
+
p server.connection #=> :postgresql
|
212
|
+
#
|
213
|
+
# errors in the child are detected and raised in the parent
|
214
|
+
#
|
215
|
+
slave = Slave.new('object' => Server.new){|s| s.typo} #=> raises an error!
|
216
|
+
|
217
|
+
~ > ruby samples/b.rb
|
218
|
+
|
219
|
+
:postgresql
|
220
|
+
./lib/slave.rb:276:in `initialize': undefined method `typo' for #<Server:0xb7573350> (NoMethodError)
|
221
|
+
from samples/b.rb:22:in `new'
|
222
|
+
from samples/b.rb:22
|
223
|
+
|
224
|
+
<========< samples/c.rb >========>
|
129
225
|
|
130
|
-
|
131
|
-
<li>pulse_rate
|
226
|
+
~ > cat samples/c.rb
|
132
227
|
|
133
|
-
|
134
|
-
|
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
|
+
"this is run only in the child"
|
235
|
+
@pid = Process.pid
|
236
|
+
end
|
237
|
+
attr 'pid'
|
238
|
+
end
|
135
239
|
|
136
|
-
|
137
|
-
|
240
|
+
slave = Slave.new{ Server.new }
|
241
|
+
server = slave.object
|
138
242
|
|
139
|
-
|
140
|
-
|
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
|
+
~ > 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
|
+
<========< samples/d.rb >========>
|
259
|
+
|
260
|
+
~ > 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
|
+
~ > ruby samples/d.rb
|
273
|
+
|
274
|
+
"parent"
|
275
|
+
|
276
|
+
<========< samples/e.rb >========>
|
277
|
+
|
278
|
+
~ > 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
|
+
~ > ruby samples/e.rb
|
293
|
+
|
294
|
+
"child"
|
295
|
+
</pre>
|
141
296
|
|
142
297
|
</div>
|
143
298
|
|