DeepConnect 0.4.06

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,151 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # port.rb -
4
+ # Copyright (C) 1996-2010 Keiju ISHITSUKA
5
+ # (Penta Advanced Labrabries, Co.,Ltd)
6
+ #
7
+ # --
8
+ #
9
+ #
10
+ #
11
+
12
+ require "deep-connect/event"
13
+
14
+ module DeepConnect
15
+ class Port
16
+
17
+ PACK_n_SIZE = [1].pack("n").size
18
+ PACK_N_SIZE = [1].pack("N").size
19
+
20
+ def initialize(sock)
21
+ @io = sock
22
+ @peeraddr = @io.peeraddr
23
+ @session = nil
24
+ end
25
+
26
+ def close
27
+ @io.close
28
+ end
29
+
30
+ def shutdown_reading
31
+ @io.shutdown(Socket::SHUT_RD)
32
+ end
33
+
34
+ def addr
35
+ @io.addr
36
+ end
37
+
38
+ def peeraddr
39
+ @peeraddr
40
+ end
41
+
42
+ def attach(session)
43
+ @session = session
44
+ end
45
+
46
+ def import2
47
+ # puts "IMPORT: start0"
48
+ # sz = read(PACK_N_SIZE).unpack("N").first
49
+ # bin = read(sz)
50
+ a = Marshal.load(@io)
51
+ begin
52
+ # ijijć, ōŃňů|ůČ??8Ĺī??-ĢĪ.
53
+ ev = Event.materialize(@session, a.first, *a)
54
+ rescue
55
+ p $!, $@
56
+ raise
57
+ end
58
+ puts "IMPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
59
+ ev
60
+ end
61
+
62
+ def import
63
+ # puts "IMPORT: start0"
64
+ sz = read(PACK_N_SIZE).unpack("N").first
65
+ bin = read(sz)
66
+ begin
67
+ a = Marshal.load(bin)
68
+ rescue
69
+ p bin
70
+ p $!, $@
71
+ raise
72
+ end
73
+ begin
74
+ # ここで, ネットワーク通信発生する可能性あり.
75
+ ev = Event.materialize(@session, a.first, *a)
76
+ rescue
77
+ p $!, $@
78
+ raise
79
+ end
80
+ puts "IMPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
81
+ ev
82
+ end
83
+
84
+ def export2(ev)
85
+ puts "EXPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
86
+ bin = Marshal.dump(ev.serialize, @io)
87
+ # size = bin.size
88
+
89
+ # packet = [size].pack("N")+bin
90
+ # write(packet)
91
+ puts "EXPORT: finsh" if Conf.MESSAGE_DISPLAY
92
+ end
93
+
94
+ def export(ev)
95
+ puts "EXPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
96
+ begin
97
+ bin = Marshal.dump(ev.serialize)
98
+ rescue
99
+ puts "Exception Rised: #{$!}"
100
+ puts $@
101
+ p ev.serialize
102
+ raise
103
+ end
104
+ size = bin.size
105
+
106
+ packet = [size].pack("N")+bin
107
+ write(packet)
108
+ puts "EXPORT: finsh" if Conf.MESSAGE_DISPLAY
109
+ end
110
+
111
+ # def import
112
+ # sz = read(PACK_N_SIZE).unpack("N").first
113
+ # bin = read(sz).unpack("a#{sz}")
114
+ # a = Marshal.load(bin.first)
115
+ # ev = Event.materialize(@session, a.first, *a)
116
+ # puts "IMPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
117
+ # ev
118
+ # end
119
+
120
+ # def export(ev)
121
+ # puts "EXPORT: #{ev.inspect}" if Conf.MESSAGE_DISPLAY
122
+ # s = Marshal.dump(ev.serialize)
123
+ # size = s.size
124
+ # packet = [size, s].pack("Na#{size}")
125
+ # write(packet)
126
+ # end
127
+
128
+ def read(n)
129
+ begin
130
+ packet = @io.read(n)
131
+ fail EOFError, "socket closed" unless packet
132
+ # DC::Raise ProtocolError unless packet.size == n
133
+ packet
134
+ rescue Errno::ECONNRESET, EOFError
135
+ puts "WARN: read中に[#{peeraddr.join(', ')}]の接続が切れました"
136
+ DC::Raise DisconnectClient, peeraddr
137
+ end
138
+ end
139
+
140
+ def write(packet)
141
+ begin
142
+ @io.write(packet)
143
+ # @io.flush
144
+ rescue Errno::ECONNRESET
145
+ puts "WARN: write中に[#{peeraddr.join(', ')}]の接続が切れました"
146
+ DC::Raise DisconnectClient, peeraddr
147
+ end
148
+ end
149
+ end
150
+ end
151
+
@@ -0,0 +1,422 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # reference.rb -
4
+ # Copyright (C) 1996-2010 Keiju ISHITSUKA
5
+ # (Penta Advanced Labrabries, Co.,Ltd)
6
+ #
7
+ # --
8
+ #
9
+ #
10
+ #
11
+
12
+ require "deep-connect/class-spec-space"
13
+
14
+ module DeepConnect
15
+ class Reference
16
+
17
+ preserved = [
18
+ :__id__, :object_id, :__send__, :public_send, :respond_to?, :send,
19
+ :instance_eval, :instance_exec, :extend, "!".intern
20
+ ]
21
+ instance_methods.each do |m|
22
+ next if preserved.include?(m.intern)
23
+ alias_method "__deep_connect_org_#{m}", m
24
+ undef_method m
25
+ end
26
+
27
+ # session ローカルなプロキシを生成
28
+ # [クラス名, 値]
29
+ # [クラス名, ローカルSESSION, 値]
30
+ def Reference.serialize(deep_space, value, spec = nil)
31
+ if spec
32
+ return Reference.serialize_with_spec(deep_space, value, spec)
33
+ end
34
+
35
+ if value.__deep_connect_reference?
36
+ if deep_space == value.deep_space
37
+ [value.__deep_connect_real_class, value.csid, value.peer_id, :PEER_OBJECT]
38
+ else
39
+ uuid = value.deep_space.peer_uuid.dup
40
+ if uuid[0] == "127.0.0.1" || uuid[0] == "::ffff:127.0.0.1"
41
+ uuid[0] = :SAME_UUIDADDR
42
+ end
43
+
44
+ [value.__deep_connect_real_class, value.csid, value.peer_id, uuid]
45
+ end
46
+ else
47
+ case value
48
+ when *Organizer::immutable_classes
49
+ [value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
50
+ else
51
+ object_id = deep_space.set_root(value)
52
+ csid = deep_space.my_csid_of(value)
53
+ [Reference, csid, object_id]
54
+ end
55
+ end
56
+ end
57
+
58
+ def Reference.serialize_with_spec(deep_space, value, spec)
59
+ if value.__deep_connect_reference?
60
+ if deep_space == value.deep_space
61
+ [value.__deep_connect_real_class, value.csid, value.peer_id, :PEER_OBJECT]
62
+ else
63
+ uuid = value.deep_space.peer_uuid.dup
64
+ if uuid[0] == "127.0.0.1" || uuid[0] == "::ffff:127.0.0.1"
65
+ uuid[0] = :SAME_UUIDADDR
66
+ end
67
+
68
+ [value.__deep_connect_real_class, value.csid, value.peer_id, uuid]
69
+ end
70
+ elsif Organizer::absolute_immutable_classes.include?(value.class)
71
+ [value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
72
+ else
73
+ case spec
74
+ when MethodSpec::DefaultParamSpec
75
+ Reference.serialize(deep_space, value)
76
+ when MethodSpec::RefParamSpec
77
+ object_id = deep_space.set_root(value)
78
+ csid = deep_space.my_csid_of(value)
79
+ [Reference, csid, object_id]
80
+ when MethodSpec::ValParamSpec
81
+ serialize_val(deep_space, value, spec)
82
+ when MethodSpec::DValParamSpec
83
+ # 第2引数意味なし
84
+ [value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
85
+ else
86
+ raise ArgumentError,
87
+ "argument is only specified(#{MethodSpec::ARG_SPEC.join(', ')})(#{spec})"
88
+ end
89
+ end
90
+ end
91
+
92
+ def Reference.serialize_val(deep_space, value, spec)
93
+ case value
94
+ when *Organizer::immutable_classes
95
+ [value.__deep_connect_real_class, value.__deep_connect_real_class.name, value]
96
+ else
97
+ [:VAL, value.__deep_connect_real_class.name,
98
+ [value.__deep_connect_real_class, value.deep_connect_serialize_val(deep_space)]]
99
+ end
100
+ end
101
+
102
+ def Reference.materialize(deep_space, type, csid, object_id, uuid=nil)
103
+ if type == Reference
104
+ if uuid
105
+ if uuid == :PEER_OBJECT
106
+ deep_space.root(object_id)
107
+ else
108
+ if uuid[0] == :SAME_UUIDADDR
109
+ uuid[0] = deep_space.peer_uuid[0].dup
110
+ end
111
+ peer_deep_space = deep_space.organizer.deep_space(uuid)
112
+ peer_deep_space.register_root_to_peer(object_id)
113
+ type.new(peer_deep_space, csid, object_id)
114
+ end
115
+ else
116
+ type.new(deep_space, csid, object_id)
117
+ end
118
+ else
119
+ if type == :VAL
120
+ materialize_val(deep_space, type,
121
+ csid, object_id[0], object_id[1])
122
+ else
123
+ # 即値
124
+ object_id
125
+ end
126
+ end
127
+ end
128
+
129
+ def Reference.materialize_val(deep_space, type, csid, klass, value)
130
+ klass.deep_connect_materialize_val(deep_space, value)
131
+ end
132
+
133
+ # def Reference.register(deep_space, o)
134
+ # deep_space.peer.set_root(o)
135
+ # Reference.new(session, o.id)
136
+ # end
137
+
138
+ def Reference.new(deep_space, csid, peer_id)
139
+ if r = deep_space.import_reference(peer_id)
140
+ return r
141
+ end
142
+ r = super
143
+ deep_space.register_import_reference(r)
144
+ r
145
+ end
146
+
147
+ def initialize(deep_space, csid, peer_id)
148
+ @deep_space = deep_space
149
+ @csid = csid
150
+ @peer_id = peer_id
151
+ end
152
+
153
+ attr_reader :deep_space
154
+ alias deepspace deep_space
155
+ attr_reader :csid
156
+ attr_reader :peer_id
157
+
158
+ def peer
159
+ @deep_space.root(@peer_id)
160
+ end
161
+
162
+ def release
163
+ @deep_space.deregister_import_reference_id(self)
164
+ end
165
+
166
+ # TO_METHODS = [:to_ary, :to_str, :to_int, :to_regexp]
167
+ # TO_METHODS = [:to_ary, :to_str, :to_int, :to_regexp, :to_splat]
168
+
169
+ def method_missing(method, *args, &block)
170
+ puts "SEND MESSAGE: #{self.inspect} #{method.id2name}" if Conf.DISPLAY_MESSAGE_TRACE
171
+
172
+ # if TO_METHODS.include?(method)
173
+ # return self.dc_dup.send(method)
174
+ # end
175
+ begin
176
+ if iterator?
177
+ @deep_space.session.send_to(self, method, args, &block)
178
+ else
179
+ @deep_space.session.send_to(self, method, args)
180
+ end
181
+ # rescue NoMethodError
182
+ # p $@
183
+ # p $!
184
+ # super
185
+ end
186
+ end
187
+
188
+ def asynchronus_send_with_callback(method, *args, &callback)
189
+ @deep_space.session.asyncronus_send_to(self, method, args, callback)
190
+ end
191
+ alias asynchronus_send asynchronus_send_with_callback
192
+
193
+ # def peer_to_s
194
+ # @deep_space.session.send_to(self, :to_s)
195
+ # end
196
+
197
+ # def peer_inspect
198
+ # @deep_space.session.send_to(self, :inspect)
199
+ # end
200
+
201
+ # def peer_class
202
+ # @deep_space.session.send_to(self, :class)
203
+ # end
204
+
205
+ # def to_s
206
+ # @deep_space.session.send_to(self, :to_s)
207
+ # end
208
+
209
+ # def to_a
210
+ # a = []
211
+ # @deep_space.session.send_to(self, :to_a).each{|e| a.push e}
212
+ # a
213
+ # end
214
+
215
+ # def =~(other)
216
+ # @deep_space.session.send_to(self, :=~, other)
217
+ # end
218
+
219
+ # def ===(other)
220
+ # @deep_space.session.send_to(self, :===, other)
221
+ # end
222
+
223
+ # def id
224
+ # @deep_space.session.send_to(self, :id)
225
+ # end
226
+
227
+ # def coerce(other)
228
+ # return other, peer
229
+ # end
230
+
231
+ def __deep_connect_reference?
232
+ true
233
+ end
234
+ alias dc_reference? __deep_connect_reference?
235
+
236
+ def __deep_connect_real_class
237
+ Reference
238
+ end
239
+
240
+ class UndefinedClass;end
241
+
242
+ def peer_class
243
+ return @peer_class if @peer_class
244
+ begin
245
+ @peer_class = self.class.dc_deep_copy
246
+ rescue
247
+ @peer_class = UndefinedClass
248
+ end
249
+ @peer_class
250
+ end
251
+
252
+ def respond_to?(m, include_private = false)
253
+ # m = m.intern
254
+ # if m != :to_ary && super
255
+ # return true
256
+ # end
257
+ return true if super
258
+ return @deep_space.session.send_to(self, :respond_to?, [m, include_private])
259
+ end
260
+
261
+ # ここは, オブジェクトの同値性を用いていない
262
+ # def ==(obj)
263
+ # return true if obj.equal?(self)
264
+ #
265
+ ## self.deep_connect_copy == obj
266
+ # false
267
+ # end
268
+ def ==(obj)
269
+ obj.__deep_connect_reference? &&
270
+ @deep_space == obj.deep_space &&
271
+ @peer_id == obj.peer_id
272
+ end
273
+
274
+ alias eql? ==
275
+
276
+ def equal?(obj)
277
+ self.object_id == obj.object_id
278
+ end
279
+
280
+ def hash
281
+ @deep_space.object_id ^ @peer_id
282
+ end
283
+
284
+ def kind_of?(klass)
285
+ if klass.__deep_connect_reference?
286
+ @deep_space.session.send_to(self, :kind_of?, klass)
287
+ else
288
+ self.peer_class <= klass
289
+ end
290
+ end
291
+
292
+ def nil?
293
+ false
294
+ end
295
+
296
+ # def ===(other)
297
+ # if other.__deep_connect_reference?
298
+ # @deep_space.session.send_to(self, :===, other)
299
+ # else
300
+ # case other
301
+ # when Class
302
+ # self.peer_class <= klass
303
+ # end
304
+ # end
305
+ # end
306
+
307
+ # def marshal_dump
308
+ # Reference.serialize(@deep_space, self)
309
+ # end
310
+
311
+ # def marshal_load(obj)
312
+ # Reference.materialize(
313
+ # end
314
+
315
+ # def marshal_load(obj)
316
+ # Reference.materialize(
317
+ # end
318
+
319
+ # def to_ary
320
+ # if respond_to?(:to_ary)
321
+ # p "AAAAAAA"
322
+ # self.dc_dup.to_ary
323
+ # p "BBBBBBBB"
324
+ # else
325
+ # # raise NoMethodError.new("undefined method `to_ary' for #{self}@@@", :to_ary)
326
+ # raise NoMethodError, "to_ary"
327
+ # end
328
+ # end
329
+
330
+ # def to_str
331
+ # if respond_to?(:to_str)
332
+ # self.dc_dup.to_str
333
+ # end
334
+ # end
335
+
336
+ # def to_a
337
+ # self.dc_dup.to_a
338
+ # end
339
+
340
+ def to_s(force = false)
341
+ if !force && /deep-connect/ =~ caller(1).first
342
+ unless /deep-connect\/test/ =~ caller(1).first
343
+ return __deep_connect_org_to_s
344
+ end
345
+ end
346
+
347
+ if @deep_space.status == :SERVICING
348
+ @deep_space.session.send_to(self, :to_s)
349
+ else
350
+ "(no service)"
351
+ end
352
+ end
353
+
354
+ def inspect(force = false)
355
+ if !force && /deep-connect/ =~ caller(1).first
356
+ unless /deep-connect\/test/ =~ caller(1).first
357
+ return sprintf("<DC::Ref: deep_space=%s csid=%s id=%x>",
358
+ @deep_space.to_s,
359
+ @csid,
360
+ @peer_id)
361
+ end
362
+ end
363
+
364
+ if Conf.DEBUG_REFERENCE
365
+ sprintf("<DC::Ref[deep_space=%s csid=%s id=%x]: %s>",
366
+ @deep_space.to_s,
367
+ @csid,
368
+ @peer_id,
369
+ to_s)
370
+ else
371
+ sprintf("<DC::Ref: %s>", to_s(true))
372
+ end
373
+ end
374
+
375
+ def peer_inspect
376
+ begin
377
+ @deep_space.session.send_to(self, :inspect)
378
+ rescue SessionServiceStopped
379
+ sprintf("<DC::Ref[deep_space=%s csid=%s id=%x]: %s>",
380
+ @deep_space.to_s,
381
+ @csid,
382
+ @peer_id,
383
+ "(service stoped)")
384
+ end
385
+ end
386
+
387
+ def my_inspect
388
+ __deep_connect_org_inspect
389
+ end
390
+
391
+ def deep_connect_dup
392
+ @deep_space.session.send_to(self, :deep_connect_dup)
393
+ end
394
+ alias dc_dup deep_connect_dup
395
+
396
+ def deep_connect_deep_copy
397
+ @deep_space.session.send_to(self, :deep_connect_deep_copy)
398
+ end
399
+ alias dc_deep_copy deep_connect_deep_copy
400
+ end
401
+ end
402
+
403
+ class Object
404
+ def __deep_connect_reference?
405
+ false
406
+ end
407
+ alias dc_reference? __deep_connect_reference?
408
+
409
+ def __deep_connect_real_class
410
+ self.class
411
+ end
412
+ end
413
+
414
+ class Module
415
+ def ===(other)
416
+ other.kind_of?(self)
417
+ end
418
+ end
419
+
420
+
421
+
422
+