Class: Emptyd::Session

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

Constant Summary collapse

@@sessions =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options, &callback) ⇒ Session

Returns a new instance of Session.



299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/emptyd.rb', line 299

def initialize options, &callback
  keys = options[:keys]
  @interactive = !!options[:interactive]
  @logger = options[:logger]
  @uuid = SecureRandom.uuid
  @@sessions[@uuid] = self
  @keys = keys
  @connections = Hash[keys.map{|h| [h, Connection[h, @logger]]}]
  @connections.each_value{|h| h.bind self}
  @queue = EM::Queue.new
  @running = {}
  @dead = false
  @terminated = {}
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



284
285
286
# File 'lib/emptyd.rb', line 284

def logger
  @logger
end

#queueObject (readonly)

Returns the value of attribute queue.



284
285
286
# File 'lib/emptyd.rb', line 284

def queue
  @queue
end

#uuidObject (readonly)

Returns the value of attribute uuid.



284
285
286
# File 'lib/emptyd.rb', line 284

def uuid
  @uuid
end

Class Method Details

.[](uuid) ⇒ Object



291
292
293
# File 'lib/emptyd.rb', line 291

def self.[](uuid)
  @@sessions[uuid] or raise KeyError, "no such session"
end

.idsObject



287
288
289
# File 'lib/emptyd.rb', line 287

def self.ids
  @@sessions.keys
end

Instance Method Details

#<<(data) ⇒ Object



374
375
376
377
378
379
380
# File 'lib/emptyd.rb', line 374

def << data
  @running.each do |k,v|
    if v.respond_to? :send_data
      v.send_data data
    end
  end
end

#callback(h, e, c = nil) ⇒ Object



394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/emptyd.rb', line 394

def callback(h,e,c=nil)
  EM.next_tick do
    @logger.debug [h.key,e,c.nil?]
    case e
    when :init
      @queue.push [h.key,:start,nil]
      @running[h.key] = c
    when :close, :error
      h.unbind self unless @dead or not @connections.include? h.key
      @connections.delete h.key
      @queue.push [h.key,:dead,c] if e == :error
      @queue.push [h.key,:done,nil]
      @running.delete h.key
      if done?
        @queue.push [nil,:done,nil] 
        @logger.debug "run is done."
      else
        @logger.debug "#{@running.size} connections pending"
      end
    else
      @logger.error "Session#run: unexpected callback #{e}"
    end
  end
end

#dead?Boolean

Returns:

  • (Boolean)


338
339
340
# File 'lib/emptyd.rb', line 338

def dead?
  @dead
end

#destroyObject



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/emptyd.rb', line 314

def destroy
  @logger.debug "Destroying session #{@uuid}"
  @logger.debug @running.map{|h,v| [h, v.class.name]}
  @running.each do |h,v| 
    if v.respond_to? :close
      @logger.debug "Closing channel for #{h}"
      v.close
    end
  end
  @connections.each_value do |h| 
    callback h, :close, "user"
    h.unbind self
  end
  @dead = true
end

#destroy!Object



330
331
332
# File 'lib/emptyd.rb', line 330

def destroy!
  @@sessions.delete @uuid
end

#done?Boolean

Returns:

  • (Boolean)


334
335
336
# File 'lib/emptyd.rb', line 334

def done?
  @running.empty?
end

#interactive?Boolean

Returns:

  • (Boolean)


295
296
297
# File 'lib/emptyd.rb', line 295

def interactive?
  @interactive
end

#run(cmd) ⇒ Object



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

def run cmd
  dead = @connections.values.select(&:dead?)
  alive = @connections.values.reject(&:dead?)
  @queue.push [nil,:dead,dead.map(&:key)]
  @queue.push [nil,:done,nil] if alive.empty?
  alive.each { |h| @running[h.key] = true }
  alive.each do |h|
    h.run(cmd, self) { |h,e,c| callback h,e,c }
  end
end

#statusObject



353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/emptyd.rb', line 353

def status
  {
    :children => Hash[@keys.map{|k| [k, 
      @terminated[k] ? :terminated :
      @running[k] == true ? :pending : 
      @running[k] ? :running : 
      @connections[k] ? 
        @connections[k].dead? ? :dead : :unknown
        : :done]}],
    :dead => @dead
  }
end

#terminate(key) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
# File 'lib/emptyd.rb', line 382

def terminate key
  return if @terminated[key]
  chan = @running.delete key
  conn = @connections.delete key
  chan.close if chan.respond_to? :close
  if conn
    callback conn, :close, "user"
    conn.unbind self 
  end
  @terminated[key] = true
end

#write(key, data) ⇒ Object

Raises:

  • (KeyError)


366
367
368
369
370
371
372
# File 'lib/emptyd.rb', line 366

def write key, data
  v = @running[key]
  raise KeyError unless @keys.include?(key)
  if v.respond_to? :send_data
    v.send_data data
  end
end