Class: Edoors::Spin

Inherits:
Room show all
Defined in:
lib/edoors/spin.rb

Instance Attribute Summary collapse

Attributes inherited from Iota

#name, #parent, #path, #spin, #viewer

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Room

#add_iota, #add_link, from_particle, #search_down, #send_p, #send_sys_p, #start!, #stop!

Methods inherited from Iota

#receive_p, #resume!, #start!, #stop!

Constructor Details

#initialize(n, o = {}) ⇒ Spin

creates a Spin object from the arguments.

Parameters:

  • n (String)

    the name of this Spin

  • o (Hash) (defaults to: {})

    a customizable set of options

Options Hash (o):

  • output ('debug_garbage'String Symbol)

    debug information about automatic garbage

  • output ('debug_routing'String Symbol)

    debug information about routing

  • if ('hibernation'Boolean)

    set to true Iota#start! won't be called within Spin#spin!

  • composed ('inner_room'Hash)

    of 2 keys, 'iotas' and 'links' use to repopulate the super class Room

  • list ('app_fifo'Array)

    of Particle to feed @app_fifo

  • list ('sys_fifo'Array)

    of Particle to feed @sys_fifo



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/edoors/spin.rb', line 45

def initialize n, o={}
    super n, nil
    #
    @pool       = {}    # per particle class free list
    @world      = {}    # global iotas index
    @sys_fifo   = []    # system particles fifo list
    @app_fifo   = []    # application particles fifo list
    #
    @run = false
    @hibernation    = o['hibernation']||false
    @hibernate_path = 'edoors-hibernate-'+n+'.json'
    @debug_garbage  = o[:debug_garbage]||o['debug_garbage']||false
    @debug_routing  = o[:debug_routing]||o['debug_routing']||false
    #
    if not o.empty?
        room = o['inner_room']
        if room
            room['iotas'].each do |name,iota|
                eval( iota['kls'] ).json_create(iota.merge!('parent'=>self))
            end
            room['links'].each do |src,links|
                links.each do |link|
                    add_link Edoors::Link.json_create(link)
                end
            end
        end
        o['app_fifo'].each do |particle|
            @app_fifo << Edoors::Particle.json_create(particle.merge!('spin'=>self))
        end if o['app_fifo']
        o['sys_fifo'].each do |particle|
            @sys_fifo <<  Edoors::Particle.json_create(particle.merge!('spin'=>self))
        end if o['sys_fifo']
    end
end

Instance Attribute Details

#debug_garbageObject

Returns the value of attribute debug_garbage.



80
81
82
# File 'lib/edoors/spin.rb', line 80

def debug_garbage
  @debug_garbage
end

#debug_routingObject

Returns the value of attribute debug_routing.



80
81
82
# File 'lib/edoors/spin.rb', line 80

def debug_routing
  @debug_routing
end

#hibernate_pathObject

Returns the value of attribute hibernate_path.



80
81
82
# File 'lib/edoors/spin.rb', line 80

def hibernate_path
  @hibernate_path
end

#runObject

Returns the value of attribute run.



80
81
82
# File 'lib/edoors/spin.rb', line 80

def run
  @run
end

Class Method Details

.json_create(o) ⇒ Object

creates a Spin object from a JSON data

Parameters:

  • o (Hash)

    belongs to JSON parser

Raises:

  • Edoors::Exception if the json kls attribute is wrong



106
107
108
109
# File 'lib/edoors/spin.rb', line 106

def self.json_create o
    raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
    self.new o['name'], o
end

.resume!(path) ⇒ Object

resumes the system from the given hibernation file

Parameters:

  • path (String)

    the hibernation file to load the system from



247
248
249
# File 'lib/edoors/spin.rb', line 247

def self.resume! path
    self.json_create JSON.load File.open(path,'r') { |f| f.read }
end

Instance Method Details

#add_to_world(iota) ⇒ Object

add the given Iota to the global Hash

Parameters:

  • iota (Iota)

    the Iota to register

See Also:

  • @world hash is used for routing


117
118
119
# File 'lib/edoors/spin.rb', line 117

def add_to_world iota
    @world[iota.path] = iota
end

#clear!Object

clears all the structures



133
134
135
136
137
138
139
140
# File 'lib/edoors/spin.rb', line 133

def clear!
    @links.clear
    @iotas.clear
    @world.clear
    @pool.clear
    @sys_fifo.clear
    @app_fifo.clear
end

#hibernate!(path = nil) ⇒ Object

sends the system into hibernation

the system is serialized into JSON data and flushed to disk

Parameters:

  • path (String) (defaults to: nil)

    the path to the hibernation file



238
239
240
241
# File 'lib/edoors/spin.rb', line 238

def hibernate! path=nil
    @hibernation = true
    File.open(path||@hibernate_path,'w') do |f| f << JSON.pretty_generate(self) end
end

#post_p(p) ⇒ Object

add the given Particle to the application Particle fifo

Parameters:



177
178
179
# File 'lib/edoors/spin.rb', line 177

def post_p p
    @app_fifo << p
end

#post_sys_p(p) ⇒ Object

add the given Particle to the system Particle fifo

Parameters:



185
186
187
# File 'lib/edoors/spin.rb', line 185

def post_sys_p p
    @sys_fifo << p
end

#process_sys_p(p) ⇒ Object

process the given particle

Parameters:

  • p (Particle)

    the Particle to be processed



193
194
195
196
197
198
199
200
# File 'lib/edoors/spin.rb', line 193

def process_sys_p p
    if p.action==Edoors::SYS_ACT_HIBERNATE
        stop!
        hibernate! p[FIELD_HIBERNATE_PATH]
    else
        super p
    end
end

#release_p(p) ⇒ Object

Note:

the Particle is stored into Hash @pool to be reused as soon as needed

releases the given Particle



150
151
152
153
154
155
156
157
# File 'lib/edoors/spin.rb', line 150

def release_p p
    # hope there is no circular loop
    while p2=p.merged_shift
        release_p p2
    end
    p.reset!
    ( @pool[p.class] ||= [] ) << p
end

#require_p(p_kls) ⇒ Object

Note:

if there is no Particle of the given Class, one is created

requires a Particle of the given Class

Parameters:

  • p_kls (Class)

    the desired Class of Particle



165
166
167
168
169
170
171
# File 'lib/edoors/spin.rb', line 165

def require_p p_kls
    l = @pool[p_kls]
    return p_kls.new if l.nil?
    p = l.pop
    return p_kls.new if p.nil?
    p
end

#search_world(path) ⇒ Object

search the global Hash for the matching Iota

Parameters:

  • path (String)

    the path to the desired Iota

See Also:

  • @world hash is used for routing


127
128
129
# File 'lib/edoors/spin.rb', line 127

def search_world path
    @world[path]
end

#spin!Object

starts the system mainloop

first Iota#start! is called on each children unless the system is resuming from hibernation then while there is Particle in the fifo, first process all system Particle then 1 application Particle after all Iota#stop! is called on each children, unless the system is going into hibernation



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/edoors/spin.rb', line 208

def spin!
    start!
    @run = true
    @hibernation = false
    while @run and (@sys_fifo.length>0 or @app_fifo.length>0)
        while @run and @sys_fifo.length>0
            p = @sys_fifo.shift
            p.dst.process_sys_p p
        end
        while @run and @app_fifo.length>0
            p = @app_fifo.shift
            p.dst.process_p p
            break
        end
    end
    stop!
end

#stop_spinning!Object

stops the spinning



228
229
230
# File 'lib/edoors/spin.rb', line 228

def stop_spinning!
    @run=false
end

#to_json(*a) ⇒ Object

called by JSON#generate to serialize the Spin object into JSON data

Parameters:

  • a (Array)

    belongs to JSON generator



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/edoors/spin.rb', line 86

def to_json *a
    {
        'kls'           => self.class.name,
        'timestamp'     => Time.now,
        'name'          => @name,
        'hibernation'   => @hibernation,
        'inner_room'    => { :iotas=>@iotas, :links=>@links },
        'sys_fifo'      => @sys_fifo,
        'app_fifo'      => @app_fifo,
        'debug_garbage' => @debug_garbage,
        'debug_routing' => @debug_routing
    }.to_json(*a)
end