class FSPSocket::PSocket

Attributes

id[R]

Public Class Methods

new(*args) click to toggle source
# File lib/fspsocket.rb, line 39
def initialize(*args)
  @host = Socket.gethostname
  @pid = Process.pid
  @id = [@host, @pid, @@id_count].join('_')
  @@id_count += 1
  if args.length == 1
    @block = args[0]
  end
  @sock_buf = []
  Manager.instance.add_observer self
  init_channel
end
open(dst_id, block) click to toggle source
# File lib/fspsocket.rb, line 125
def PSocket.open(dst_id, block)
  sock = PSocket.new(block)
  if (dst_id.kind_of?(Enumerable))
    dst_id.each do |item|
      sock.connect_channel([@@base, item].join(File::SEPARATOR))
    end
  else
    sock.connect_channel([@@base, dst_id].join(File::SEPARATOR))
  end
  return sock
end
write_to(path, data) click to toggle source
# File lib/fspsocket.rb, line 162
def PSocket.write_to(path, data)
  @@log.info "write_to #{path} #{data}"
  File::open(path, "a+") do |f|
    h = {:time=>Time.now, :data=>URI.encode(data)}
    f.puts(h.to_json)
  end    
end

Public Instance Methods

close() click to toggle source
# File lib/fspsocket.rb, line 148
def close
  delete_channel
  PSocket.write_to(@dst_cpath, "BYE #{@id}") 
end
connect(dst_id) click to toggle source

used to connect to multiple destinations

# File lib/fspsocket.rb, line 138
def connect(dst_id)
  if (dst_id.kind_of?(Enumerable))
    dst_id.each do |item|
      connect_channel([@@base, item].join(File::SEPARATOR))
    end
  else
    connect_channel([@@base, dst_id].join(File::SEPARATOR))
  end
end
connect_channel(dst_fullpath) click to toggle source
# File lib/fspsocket.rb, line 100
def connect_channel(dst_fullpath)
  # 1. create my controls channel in the other's controls dir
  #    /socks/dstid/controls/myid
  mycpath = [dst_fullpath, :controls, @id].join(File::SEPARATOR)
  @connected << mycpath
  FileUtils.touch(mycpath)
  sleep 1 # XXX for timing purpose
  # 2. let the other know my path
  PSocket.write_to(mycpath, "HELLO #{@id}")    
end
delete_channel() click to toggle source
# File lib/fspsocket.rb, line 111
def delete_channel
  @connected.each do |path|
    if FileTest.exist? path
      File::delete path
    end
  end

  path = [@@base, @id].join(File::SEPARATOR)
  if FileTest.exist? path
    File::delete [path, :data].join(File::SEPARATOR)
    FileUtils.rm_rf path
  end    
end
puts(data) click to toggle source
# File lib/fspsocket.rb, line 157
def puts(data)
  #@@log.debug "XXX puts: #{@dpath} #{data}"
  PSocket.write_to(@dpath, data)
end
Also aliased as: _puts
received(&block) click to toggle source
# File lib/fspsocket.rb, line 153
def received(&block)
  @recv_block = block
end
update(msg) click to toggle source

msg => path, msg => data in JSON delimited with ā€˜n’

# File lib/fspsocket.rb, line 71
def update(msg)
  @@log.info "--- update #{msg}"
  # msg[1]:data part can contain more than one line
  msg[1].each_line do |item|
    h = JSON.parse(item) 
    d = h.fetch(:data.to_s) 
    ud = URI.unescape(d)
    ar = ud.split
    if ar[0] == "HELLO"
      @@log.info "---got HELLO: #{ar[1]}"
      Manager.instance.add_file([@@base, ar[1], :data].join(File::SEPARATOR))
      # XXX
      mycpath = [@@base, ar[1], :controls, @id].join(File::SEPARATOR)
      FileUtils.touch(mycpath)
      sleep 1 # XXX for timing purpose
      PSocket.write_to(mycpath, "OK #{@id}")
    elsif ar[0] == "OK"
      @@log.info "---got OK: #{ar[1]}"
      Manager.instance.add_file([@@base, ar[1], :data].join(File::SEPARATOR))
      @block.call(method(:received))    
    elsif ar[0] == "BYE"
      @@log.info "---got BYE: #{ar[1]}"
      Manager.instance.remove_file([@@base, ar[1], :data].join(File::SEPARATOR))
    else
      @recv_block.call(msg[0], ud)
    end    
  end # each
end

Private Instance Methods

_puts(data)
Alias for: puts
init_channel() click to toggle source
# File lib/fspsocket.rb, line 52
def init_channel
  unless FileTest.exist? @@base
    Dir::mkdir(@@base, 0777)
  end

  @path = [@@base, @id].join(File::SEPARATOR)
  @cpath = [@path, :controls].join(File::SEPARATOR)
  @dpath = [@path, :data].join(File::SEPARATOR)
  @connected = [] # for cleanup
  unless FileTest.exist? @path
    Dir::mkdir(@path, 0777)
    Dir::mkdir(@cpath, 0777)
    FileUtils.touch(@dpath)
  end
  Manager.instance.add_dir(@cpath)
end