Class: DeepConnect::DeepSpace

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/deep-connect/deep-space.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(org, port, local_id = nil) ⇒ DeepSpace

Returns a new instance of DeepSpace.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/deep-connect/deep-space.rb', line 20

def initialize(org, port, local_id = nil)
  @status = :INITIALIZE

  @organizer = org
  @session = Session.new(self, port, local_id)

  unless local_id
	local_id = port.peeraddr[1]
  end

  addr = port.peeraddr[3]
  ipaddr = IPAddr.new(addr)
#      ipaddr = ipaddr.ipv4_mapped if ipaddr.ipv4?
  ipaddr = ipaddr.native

  @peer_uuid = [ipaddr.to_s, local_id]

  init_class_spec_feature
  init_export_feature
  init_import_feature
end

Instance Attribute Details

#organizerObject (readonly)

Returns the value of attribute organizer.



43
44
45
# File 'lib/deep-connect/deep-space.rb', line 43

def organizer
  @organizer
end

#peer_uuidObject (readonly) Also known as: peer_id

Returns the value of attribute peer_uuid.



45
46
47
# File 'lib/deep-connect/deep-space.rb', line 45

def peer_uuid
  @peer_uuid
end

#sessionObject (readonly)

Returns the value of attribute session.



44
45
46
# File 'lib/deep-connect/deep-space.rb', line 44

def session
  @session
end

#statusObject (readonly)

Returns the value of attribute status.



42
43
44
# File 'lib/deep-connect/deep-space.rb', line 42

def status
  @status
end

Instance Method Details

#closeObject



48
49
50
# File 'lib/deep-connect/deep-space.rb', line 48

def close
  @organizer.close_deepspace(self)
end

#connectObject



52
53
54
55
56
57
58
# File 'lib/deep-connect/deep-space.rb', line 52

def connect
  @session.start

  @deregister_reference_thread = start_deregister_reference

  @status = :SERVICING
end

#delete_roots(pairs) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/deep-connect/deep-space.rb', line 167

def delete_roots(pairs)
  @export_roots_mutex.synchronize do
	pairs.each_slice(2) do |id, refcount|
	  if pair = @export_roots[id]
#	    puts "#{$$}: GC: #{id} #{refcount} #{pair.first.class} #{pair.last}"

 if (pair[1] -= refcount) == 0
   obj = @export_roots.delete(id)
   if Conf.DISPLAY_GC
		puts "#{$$}: GC: delete root: #{id} #{obj.first.to_s}"
   end
 else
   if Conf.DISPLAY_GC
		puts "#{$$}: GC: derefcount root: #{id} #{pair.first.to_s} #{pair[1]}"
		if pair.first.kind_of?(Exception)
p pair.first
p pair.first.backtrace
		end
   end
 end
	  else
 if Conf.DISPLAY_GC
   puts "#{$$}: GC: warn already deleted root: #{id.inspect}"
 end
	  end
	end
  end
end

#deregister_import_reference(ref) ⇒ Object



275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/deep-connect/deep-space.rb', line 275

def deregister_import_reference(ref)
  return deregister_import_reference_for_disable_gc(ref) unless Conf.ENABLE_GC
  status = GC.disable
  begin
	@import_reference_mutex.synchronize do
	  pair = @import_reference.delete(ref.peer_id)
	  @rev_import_reference.delete(pair.first)
	  @deregister_reference_queue.concat [ref.peer_id, pair.last]
	end
  ensure
	GC.enable unless status
	@deregister_thread.wakeup
  end
end

#deregister_import_reference_for_disable_gc(ref) ⇒ Object



290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/deep-connect/deep-space.rb', line 290

def deregister_import_reference_for_disable_gc(ref)
  status = GC.disable
  begin
	@import_reference_mutex.synchronize do
	  pair = @import_reference.delete(ref.peer_id)
	  @deregister_reference_queue.concat [ref.peer_id, pair.last]
	end
  ensure
	GC.enable unless status
	@deregister_thread.wakeup
  end
end

#deregister_import_reference_procObject



303
304
305
306
307
308
309
310
311
312
313
# File 'lib/deep-connect/deep-space.rb', line 303

def deregister_import_reference_proc
  proc do |ref_id|
	if @status == :SERVICING
	  puts "#{$$}: GC: gced id: #{ref_id}" if Conf.DISPLAY_GC
	  peer_id = @rev_import_reference.delete(ref_id)
	  pair = @import_reference.delete(peer_id)
	  @deregister_reference_queue.concat [peer_id, pair.last]
	  @deregister_thread.wakeup
	end
  end
end

#deregister_roots_to_peer(ids) ⇒ Object



359
360
361
362
# File 'lib/deep-connect/deep-space.rb', line 359

def deregister_roots_to_peer(ids)
  puts "#{$$}: GC: send deregister id: #{ids.join(' ')}" if Conf.DISPLAY_GC
  @session.deregister_root_to_peer(ids)
end

#disconnect(*opts) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/deep-connect/deep-space.rb', line 60

def disconnect(*opts)
  org_status = @status
  @status = :SERVICE_STOP
  
  @session.stop_service(*opts)
  if !opts.include?(:SESSION_CLOSED) && !opts.include?(:REQUEST_FROM_PEER)
	@session.send_disconnect
  end
  @session.stop

  @deregister_reference_thread.exit if org_status == :SERVICING
  @import_reference = nil
  @export_roots = nil
end

#import(name, waitp = false) ⇒ Object Also known as: get_service



75
76
77
# File 'lib/deep-connect/deep-space.rb', line 75

def import(name, waitp = false)
  @session.get_service(name, waitp)
end

#import_mq(name, waitp = false) ⇒ Object Also known as: get_mq



80
81
82
83
# File 'lib/deep-connect/deep-space.rb', line 80

def import_mq(name, waitp = false)
  sv = @session.import_mq(name, waitp)
  DeepMQ::CL.new(sv)
end

#import_reference(peer_id) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/deep-connect/deep-space.rb', line 212

def import_reference(peer_id)
  return import_reference_for_disable_gc(peer_id) unless Conf.ENABLE_GC

  status = GC.disable
  begin
	@import_reference_mutex.synchronize do
	  if pair = @import_reference[peer_id]
 begin
   ObjectSpace._id2ref(pair.first)
 rescue
   ref_id = @import_reference.delete(peer_id)
   @rev_import_reference.delete(ref_id)
   @deregister_reference_queue.concat [peer_id, 1]
   return nil
 end
	  else
 nil
	  end
	end
  ensure
	GC.enable unless status
  end
end

#import_reference_for_disable_gc(peer_id) ⇒ Object



236
237
238
239
240
241
242
243
244
# File 'lib/deep-connect/deep-space.rb', line 236

def import_reference_for_disable_gc(peer_id)
  @import_reference_mutex.synchronize do
	if pair = @import_reference[peer_id]
	  pair.first
	else
	  nil
	end
  end
end

#init_class_spec_featureObject

class spec feature



89
90
91
92
# File 'lib/deep-connect/deep-space.rb', line 89

def init_class_spec_feature
  # class spec
  @class_spec_space = ClassSpecSpace.new(:remote)
end

#init_export_featureObject

export root 関連メソッド



119
120
121
122
123
# File 'lib/deep-connect/deep-space.rb', line 119

def init_export_feature
  # exportしているオブジェクト
  @export_roots_mutex = Mutex.new
  @export_roots = {}
end

#init_import_featureObject

import 関連メソッド



199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/deep-connect/deep-space.rb', line 199

def init_import_feature
  # importしているオブジェクト
  # peer_id => ref_id
  @import_reference = {}
  @rev_import_reference = {}

  @import_reference_mutex = Mutex.new
  @import_reference_cv = ConditionVariable.new
  @deregister_reference_queue = []

  @deregister_thread = nil
end

#make_class_spec_cache(cspec) ⇒ Object



112
113
114
# File 'lib/deep-connect/deep-space.rb', line 112

def make_class_spec_cache(cspec)
  cache = ClassSpec.new
end

#my_csid_of(obj) ⇒ Object



103
104
105
# File 'lib/deep-connect/deep-space.rb', line 103

def my_csid_of(obj)
  Organizer::class_spec_id_of(obj)
end

#my_method_spec(obj, method) ⇒ Object



99
100
101
# File 'lib/deep-connect/deep-space.rb', line 99

def my_method_spec(obj, method)
  Organizer::method_spec(obj, method)
end

#recv_class_spec(cspecs) ⇒ Object



107
108
109
110
# File 'lib/deep-connect/deep-space.rb', line 107

def recv_class_spec(cspecs)
  cspecs.each{|cspec| add_class_spec(cspec)}
  make_class_spec_cache(cspecs.first)
end

#register_import_reference(ref) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/deep-connect/deep-space.rb', line 246

def register_import_reference(ref)
  return register_import_reference_for_disable_gc(ref) unless Conf.ENABLE_GC

  status = GC.disable
  begin
	@import_reference_mutex.synchronize do
	  if pair = @import_reference[ref.peer_id]
 pair[1] += 1
	  else
 @import_reference[ref.peer_id] = [ref.object_id, 1]
 @rev_import_reference[ref.object_id] = ref.peer_id
	  end
	end
	ObjectSpace.define_finalizer(ref, deregister_import_reference_proc)
  ensure
	GC.enable unless status
  end
end

#register_import_reference_for_disable_gc(ref) ⇒ Object



265
266
267
268
269
270
271
272
273
# File 'lib/deep-connect/deep-space.rb', line 265

def register_import_reference_for_disable_gc(ref)
  @import_reference_mutex.synchronize do
	if pair = @import_reference[ref.peer_id]
	  pair[1] += 1
	else
	  @import_reference[ref.peer_id] = [ref, 1]
	end
  end
end

#register_root_from_other_session(id) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/deep-connect/deep-space.rb', line 155

def register_root_from_other_session(id)
  obj = @organizer.id2obj(id)
  @export_roots_mutex.synchronize do
	if pair = @export_roots[id]
	  pair[1] += 1
	else
	  @export_roots[id] = [obj, 1]
	end
  end
  obj
end

#register_root_to_peer(id) ⇒ Object



353
354
355
356
357
# File 'lib/deep-connect/deep-space.rb', line 353

def register_root_to_peer(id)
  unless import_reference(id)
	@session.register_root_to_peer(id)
  end
end

#release_object(obj) ⇒ Object



125
126
127
128
129
# File 'lib/deep-connect/deep-space.rb', line 125

def release_object(obj)
  @export_roots_mutex.synchronize do
	@export_roots.delete(obj.object_id)
  end
end

#root(id) ⇒ Object Also known as: export_root



146
147
148
149
150
151
152
# File 'lib/deep-connect/deep-space.rb', line 146

def root(id)
  @export_roots_mutex.synchronize do
	pair = @export_roots.fetch(id){return IllegalObject.new(id)}
	pair.first
	#@export_roots.fetch(id){:__DEEPCONNECT_NO_VALUE__}
  end
end

#set_root(root) ⇒ Object Also known as: set_export_root



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/deep-connect/deep-space.rb', line 131

def set_root(root)
#if root.kind_of?(Proc)
#  puts "SET_ROOT: #{root}\n #{caller(0)}"
#end
  @export_roots_mutex.synchronize do
	if pair = @export_roots[root.object_id]
	  pair[1] += 1
	else
	  @export_roots[root.object_id] = [root, 1]
	end
	root.object_id
  end
end

#start_deregister_referenceObject



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/deep-connect/deep-space.rb', line 328

def start_deregister_reference
  @deregister_thread  = Thread.start {
	ids = []
	loop do
	  Thread.stop
	  Thread.exit unless @status == :SERVICING

	  ids = []
	  @import_reference_mutex.synchronize do
 status = GC.disable
 begin
   ids = @deregister_reference_queue.dup
   @deregister_reference_queue.clear
 ensure
   GC.enable unless status
 end
	  end
	  unless ids.empty?
 deregister_roots_to_peer(ids) 
	  end
	  sleep 1
	end
  }
end

#start_deregister_reference_orgObject



315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/deep-connect/deep-space.rb', line 315

def start_deregister_reference_org
  @deregister_thread  = Thread.start {
	ids = []
	while ids.push @deregister_reference_queue.pop
	  begin
 while ids.push @deregister_reference_queue.pop(true); end
	  rescue ThreadError
 deregister_roots_to_peer(ids) if @status == :SERVICING
	  end
	end
  }
end