class Emptyd::Session

Attributes

logger[R]
queue[R]
uuid[R]

Public Class Methods

[](uuid) click to toggle source
# File lib/emptyd.rb, line 291
def self.[](uuid)
  @@sessions[uuid] or raise KeyError, "no such session"
end
ids() click to toggle source
# File lib/emptyd.rb, line 287
def self.ids
  @@sessions.keys
end
new(options, &callback) click to toggle source
# 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

Public Instance Methods

<<(data) click to toggle source
# 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) click to toggle source
# 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?() click to toggle source
# File lib/emptyd.rb, line 338
def dead?
  @dead
end
destroy() click to toggle source
# 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!() click to toggle source
# File lib/emptyd.rb, line 330
def destroy!
  @@sessions.delete @uuid
end
done?() click to toggle source
# File lib/emptyd.rb, line 334
def done?
  @running.empty?
end
interactive?() click to toggle source
# File lib/emptyd.rb, line 295
def interactive?
  @interactive
end
run(cmd) click to toggle source
# 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
status() click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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