jason-o-matic-deep_test 1.2.2.5 → 1.2.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/deep_test/drbfire.rb +290 -0
  2. metadata +2 -1
@@ -0,0 +1,290 @@
1
+ # :include:README
2
+ #--
3
+ # Author:: Nathaniel Talbott.
4
+ # Copyright:: Copyright (c) 2004 Nathaniel Talbott. All rights reserved.
5
+ # License:: Ruby license.
6
+
7
+ require 'delegate'
8
+ require 'drb'
9
+ require 'timeout'
10
+
11
+ # = DRb Firewall Protocol
12
+ #
13
+ # == Prerequisites
14
+ #
15
+ # It is assumed that you already know how to use DRb; if you don't
16
+ # you'll need to go read up on it and understand the basics of how it
17
+ # works before using DRbFire. DRbFire actually wraps the standard
18
+ # protocols that DRb uses, so generally anything that applies to them
19
+ # applies to DRbFire.
20
+ #
21
+ #
22
+ # == Basic Usage
23
+ #
24
+ # Using DRbFire is quite simple, and can be summed up in four steps:
25
+ #
26
+ # 1. Start with <tt>require 'drb/drbfire'</tt>.
27
+ #
28
+ # 2. Use <tt>drbfire://</tt> instead of <tt>druby://</tt> when
29
+ # specifying the server url.
30
+ #
31
+ # 3. When calling <tt>DRb.start_service</tt> on the client, specify
32
+ # the server's uri as the uri (as opposed to the normal usage, which
33
+ # is to specify *no* uri).
34
+ #
35
+ # 4. Specify the right configuration when calling
36
+ # <tt>DRb.start_service</tt>, specifically the role to use:
37
+ # On the server:: <tt>DRbFire::ROLE => DRbFire::SERVER</tt>
38
+ # On the client:: <tt>DRbFire::ROLE => DRbFire::CLIENT</tt>
39
+ #
40
+ # So a simple server would look like:
41
+ #
42
+ # require 'drb/drbfire'
43
+ #
44
+ # front = ['a', 'b', 'c']
45
+ # DRb.start_service('drbfire://some.server.com:5555', front, DRbFire::ROLE => DRbFire::SERVER)
46
+ # DRb.thread.join
47
+ #
48
+ # And a simple client:
49
+ #
50
+ # require 'drb/drbfire'
51
+ #
52
+ # DRb.start_service('drbfire://some.server.com:5555', nil, DRbFire::ROLE => DRbFire::CLIENT)
53
+ # DRbObject.new(nil, 'drbfire://some.server.com:5555').each do |e|
54
+ # p e
55
+ # end
56
+ #
57
+ #
58
+ # == Advanced Usage
59
+ #
60
+ # You can do some more interesting tricks with DRbFire, too:
61
+ #
62
+ # <b>Using SSL</b>:: To do this, you have to set the delegate in the
63
+ # configuration (on both the server and the client) using
64
+ # <tt>DRbFire::DELEGATE => DRb::DRbSSLSocket</tt>. Other
65
+ # DRb protcols may also work as delegates, but only the
66
+ # SSL protocol is tested.
67
+ #
68
+ #
69
+ # == Caveats
70
+ #
71
+ # * DRbFire uses a 32-bit id space, meaning ids will wrap after
72
+ # approximately ~4.2 billion connections. If that's a non-theoretical
73
+ # problem for you, and you tell me about it, I'll figure out some
74
+ # way to fix it. It'd be worth it just to find out that DRbFire is
75
+ # being used in such a mind-blowing fashion.
76
+ #
77
+ # * You're limited to one _server_ per process at this point. You can
78
+ # have (and handle) as many clients as you want (well, ok, so I just
79
+ # said there's really a limit somewhere around 4.2 billion. I'm
80
+ # trying to simplify here). Again, this is possible to deal with,
81
+ # but not something that I've needed at this point and not something
82
+ # I'm guessing is terribly common. Let me know if it's a problem for
83
+ # you.
84
+
85
+
86
+ module DRbFire
87
+ # The current version.
88
+ VERSION = [0, 1, 0]
89
+
90
+ # The role configuration key.
91
+ ROLE = "#{self}::ROLE"
92
+
93
+ # The server role configuration value.
94
+ SERVER = "#{self}::SERVER"
95
+
96
+ # The client role configuration value.
97
+ CLIENT = "#{self}::CLIENT"
98
+
99
+ # The delegate configuration key.
100
+ DELEGATE = "#{self}::DELEGATE"
101
+
102
+ # Miscellaneous constants
103
+ SCHEME = "drbfire" #:nodoc:
104
+ ID_FORMAT = "N" #:nodoc:
105
+ INCOMING_CONN = "1" #:nodoc:
106
+ OUTGOING_CONN = "2" #:nodoc:
107
+ SIGNAL_CONN = "3" #:nodoc:
108
+
109
+ class Protocol < SimpleDelegator #nodoc:all
110
+ class ClientServer
111
+ attr_reader :signal_id
112
+
113
+ def initialize(uri, config)
114
+ @uri = uri
115
+ @config = config
116
+ @connection = Protocol.open(uri, config, SIGNAL_CONN)
117
+ @signal_id = @connection.read_signal_id
118
+ end
119
+
120
+ def uri
121
+ "#{@uri}?#{@signal_id}"
122
+ end
123
+
124
+ def accept
125
+ @connection.stream.read(1)
126
+ connection = Protocol.open(@uri, @config, OUTGOING_CONN)
127
+ connection.stream.write([@signal_id].pack(ID_FORMAT))
128
+ connection
129
+ end
130
+
131
+ def close
132
+ @connection.close
133
+ end
134
+ end
135
+
136
+ class ClientServerProxy
137
+ def initialize(connection, id)
138
+ @connection = connection
139
+ @id = id
140
+ @queue = Queue.new
141
+ end
142
+
143
+ def write_signal_id
144
+ @connection.stream.write([@id].pack(ID_FORMAT))
145
+ end
146
+
147
+ def push(connection)
148
+ @queue.push(connection)
149
+ end
150
+
151
+ def open
152
+ @connection.stream.write("0")
153
+ timeout(20) do
154
+ @queue.pop
155
+ end
156
+ rescue TimeoutError
157
+ raise DRb::DRbConnError, "Unable to get a client connection."
158
+ end
159
+ end
160
+
161
+ class << self
162
+ def open_server(uri, config)
163
+ if(server?(config))
164
+ @client_servers ||= {}
165
+
166
+ puts "OPEN SERVER1 #{uri}"
167
+
168
+ sock = delegate(config).open_server(uri, config)
169
+ scheme = sock.uri.match(/^(.*):\/\//)[1]
170
+ drbfire_uri = sock.uri.sub(scheme, SCHEME)
171
+ puts "OPEN SERVER2 #{drbfire_uri}\n#{caller.join("\n")}"
172
+ new(drbfire_uri, sock)
173
+
174
+ # new(uri, delegate(config).open_server(uri, config))
175
+ else
176
+ ClientServer.new(uri, config)
177
+ end
178
+ end
179
+
180
+ def open(uri, config, type=INCOMING_CONN)
181
+ unless(server?(config))
182
+ connection = new(uri, delegate(config).open(uri, config))
183
+ connection.stream.write(type)
184
+ connection
185
+ else
186
+ @client_servers[parse_uri(uri).last.to_i].open
187
+ end
188
+ end
189
+
190
+ def add_client_connection(id, connection)
191
+ if((c = @client_servers[id]))
192
+ c.push(connection)
193
+ else
194
+ end
195
+ end
196
+
197
+ def add_client_server(id, server)
198
+ @client_servers[id] = server
199
+ end
200
+
201
+ def parse_uri(uri)
202
+ if(%r{^#{SCHEME}://([^:]+):(\d+)(?:\?(.+))?$} =~ uri)
203
+ [$1, $2.to_i, $3]
204
+ else
205
+ raise DRb::DRbBadScheme, uri unless(/^#{SCHEME}/ =~ uri)
206
+ raise DRb::DRbBadURI, "Can't parse uri: #{uri}"
207
+ end
208
+ end
209
+
210
+ def uri_option(uri, config)
211
+ host, port, option = parse_uri(uri)
212
+ return "#{SCHEME}://#{host}:#{port}", option
213
+ end
214
+
215
+ private
216
+
217
+ def server?(config)
218
+ raise "Invalid configuration" unless(config.include?(ROLE))
219
+ config[ROLE] == SERVER
220
+ end
221
+
222
+ def delegate(config)
223
+ unless(defined?(@delegate))
224
+ @delegate = Class.new(config[DELEGATE] || DRb::DRbTCPSocket) do
225
+ class << self
226
+ attr_writer :delegate
227
+
228
+ def parse_uri(uri)
229
+ @delegate.parse_uri(uri)
230
+ end
231
+
232
+ def uri_option(uri, config)
233
+ @delegate.uri_option(uri, config)
234
+ end
235
+ end
236
+ end
237
+ @delegate.delegate = self
238
+ end
239
+ @delegate
240
+ end
241
+ end
242
+
243
+ attr_reader :signal_id, :uri
244
+
245
+ def initialize(uri, delegate)
246
+ super(delegate)
247
+ @uri = uri
248
+ @id = 0
249
+ @id_mutex = Mutex.new
250
+ end
251
+
252
+ def accept
253
+ while(__getobj__.instance_eval{@socket})
254
+ begin
255
+ connection = self.class.new(nil, __getobj__.accept)
256
+ rescue IOError
257
+ return nil
258
+ end
259
+ begin
260
+ type = connection.stream.read(1)
261
+ rescue
262
+ next
263
+ end
264
+ case type
265
+ when INCOMING_CONN
266
+ return connection
267
+ when OUTGOING_CONN
268
+ self.class.add_client_connection(connection.read_signal_id, connection)
269
+ next
270
+ when SIGNAL_CONN
271
+ new_id = nil
272
+ @id_mutex.synchronize do
273
+ new_id = (@id += 1)
274
+ end
275
+ client_server = ClientServerProxy.new(connection, new_id)
276
+ self.class.add_client_server(new_id, client_server)
277
+ client_server.write_signal_id
278
+ next
279
+ else
280
+ raise "Invalid type #{type}"
281
+ end
282
+ end
283
+ end
284
+
285
+ def read_signal_id
286
+ stream.read(4).unpack(ID_FORMAT).first
287
+ end
288
+ end
289
+ end
290
+ DRb::DRbProtocol.add_protocol(DRbFire::Protocol)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jason-o-matic-deep_test
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2.5
4
+ version: 1.2.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - anonymous z, Dan Manges, David Vollbracht
@@ -23,6 +23,7 @@ extra_rdoc_files:
23
23
  - README.rdoc
24
24
  - CHANGELOG
25
25
  files:
26
+ - lib/deep_test/drbfire.rb
26
27
  - lib/deep_test/database/mysql_setup_listener.rb
27
28
  - lib/deep_test/database/setup_listener.rb
28
29
  - lib/deep_test/deadlock_detector.rb