Class: Madeleine::Automatic::AutomaticSnapshotMadeleine

Inherits:
Object
  • Object
show all
Defined in:
lib/madeleine/automatic.rb

Overview

The AutomaticSnapshotMadeleine class contains an instance of the persister (default is SnapshotMadeleine) and provides additional automatic functionality.

The class is instantiated the same way as SnapshotMadeleine: madeleine_sys = AutomaticSnapshotMadeleine.new(“storage_directory”) { A.new(param1, …) } The second initialisation parameter is the persister. Supported persisters are:

  • Marshal (default)

  • YAML

  • SOAP::Marshal

  • Madeleine::ZMarshal.new(Marshal)

  • Madeleine::ZMarshal.new(YAML)

  • Madeleine::ZMarshal.new(SOAP::Marshal)

The class keeps a record of all the systems that currently exist. Each instance of the class keeps a record of Prox objects in that system by internal id (myid).

We also add functionality to take_snapshot in order to set things up so that the custom Prox object marshalling will work correctly.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(directory_name, marshaller = Marshal, persister = SnapshotMadeleine, &new_system_block) ⇒ AutomaticSnapshotMadeleine

Returns a new instance of AutomaticSnapshotMadeleine.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/madeleine/automatic.rb', line 263

def initialize(directory_name, marshaller=Marshal, persister=SnapshotMadeleine, &new_system_block)
  @sysid ||= Time.now.to_f.to_s + Thread.current.object_id.to_s # Gererate a new sysid
  @myid_count = 0
  @list = {}
  Thread.current[:system] = self # during system startup system should not create commands
  Thread.critical = true
  @@systems ||= {}  # holds systems by sysid
  @@systems[@sysid] = self
  Thread.critical = false
  @marshaller = marshaller # until attrb

  begin
    @persister = persister.new(directory_name, Automatic_marshaller, &new_system_block)
    @list.delete_if {|k,v|  # set all the prox objects that now exist to have the right sysid
      begin
        obj = ObjectSpace._id2ref(v)
        raise unless obj.respond_to?(:sysid=)
        obj.sysid = @sysid
        false
      rescue RangeError
        true # Id was to a GC'd object, delete it
      rescue RuntimeError
        true # GC'd object, and id was reused for something else
      end
    }
  ensure
    Thread.current[:system] = false
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object

Pass on any other calls to the persister



357
358
359
# File 'lib/madeleine/automatic.rb', line 357

def method_missing(symbol, *args, &block)
  @persister.send(symbol, *args, &block)
end

Instance Attribute Details

#listObject (readonly)

Returns the value of attribute list.



261
262
263
# File 'lib/madeleine/automatic.rb', line 261

def list
  @list
end

#marshallerObject

Returns the value of attribute marshaller.



260
261
262
# File 'lib/madeleine/automatic.rb', line 260

def marshaller
  @marshaller
end

#sysidObject (readonly)

Returns the value of attribute sysid.



261
262
263
# File 'lib/madeleine/automatic.rb', line 261

def sysid
  @sysid
end

Class Method Details

.systemsObject

Returns the hash containing the systems.



335
336
337
# File 'lib/madeleine/automatic.rb', line 335

def AutomaticSnapshotMadeleine.systems
  @@systems
end

Instance Method Details

#add(proxo) ⇒ Object

Add a proxy object to the list, return the myid for that object



295
296
297
298
# File 'lib/madeleine/automatic.rb', line 295

def add(proxo)  
  @list[@myid_count += 1] = proxo.object_id
  @myid_count
end

#closeObject

system before GC gets them



342
343
344
345
346
347
348
349
350
351
352
# File 'lib/madeleine/automatic.rb', line 342

def close
  begin
    @list.each_key {|k|
      ref = myid2ref(k)
      ref.sysid = nil if ref.class == Prox
    }
  rescue RangeError
    # do nothing
  end
  @persister.close
end

#myid2ref(myid) ⇒ Object

Returns a reference to the object indicated by the internal id supplied.



315
316
317
318
# File 'lib/madeleine/automatic.rb', line 315

def myid2ref(myid)
  raise "Internal id #{myid} not found" unless objid = @list[myid]
  ObjectSpace._id2ref(objid)
end

#restore(proxo) ⇒ Object

If the object already exists in the system then the existing object must be used.



303
304
305
306
307
308
309
310
311
# File 'lib/madeleine/automatic.rb', line 303

def restore(proxo)  
  if (@list[proxo.myid])
    proxo = myid2ref(proxo.myid)
  else
    @list[proxo.myid] = proxo.object_id
    @myid_count = proxo.myid if (@myid_count < proxo.myid)
  end
  proxo
end

#take_snapshotObject

Take a snapshot of the system.



322
323
324
325
326
327
328
329
330
331
# File 'lib/madeleine/automatic.rb', line 322

def take_snapshot
  begin
    Thread.current[:system] = self
    Thread.current[:snapshot_memory] = {}
    @persister.take_snapshot
  ensure
    Thread.current[:snapshot_memory] = nil
    Thread.current[:system] = false
  end
end