distributor 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ require "distributor"
2
2
  require "distributor/connector"
3
3
  require "distributor/multiplexer"
4
4
  require "json"
5
+ require "thread"
5
6
 
6
7
  class Distributor::Client
7
8
 
@@ -10,7 +11,9 @@ class Distributor::Client
10
11
  @multiplexer = Distributor::Multiplexer.new(output)
11
12
  @handlers = {}
12
13
  @processes = []
13
- @on_close = Hash.new([])
14
+ @on_close = Hash.new { |hash,key| hash[key] = Array.new }
15
+ @on_hello = []
16
+ @hookup_lock = Mutex.new
14
17
 
15
18
  # reserve a command channel
16
19
  @multiplexer.reserve(0)
@@ -20,10 +23,9 @@ class Distributor::Client
20
23
  @multiplexer.input io
21
24
  end
22
25
 
23
- # @connector.on_close(input) do |io|
24
- # p [:cl1, input]
25
- # @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
26
- # end
26
+ @connector.on_close(input) do |io|
27
+ exit 0
28
+ end
27
29
 
28
30
  # handle the command channel of the multiplexer
29
31
  @connector.handle(@multiplexer.reader(0)) do |io|
@@ -31,6 +33,8 @@ class Distributor::Client
31
33
 
32
34
  dequeue_json do |data|
33
35
  case command = data["command"]
36
+ when "hello" then
37
+ @on_hello.each { |c| c.call }
34
38
  when "close" then
35
39
  ch = data["ch"]
36
40
  @on_close[ch].each { |c| c.call(ch) }
@@ -64,14 +68,17 @@ class Distributor::Client
64
68
  end
65
69
 
66
70
  def hookup(ch, input, output=input)
67
- # handle data incoming on the multiplexer
68
- @connector.handle(@multiplexer.reader(ch)) do |io|
69
- begin
70
- data = io.readpartial(4096)
71
- # output.write "#{ch}: #{data}"
72
- output.write data
73
- rescue EOFError
74
- @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
71
+ @hookup_lock.synchronize do
72
+ # handle data incoming on the multiplexer
73
+ @connector.handle(@multiplexer.reader(ch)) do |io|
74
+ begin
75
+ data = io.readpartial(4096)
76
+ # output.write "#{ch}: #{data}"
77
+ output.write data
78
+ output.flush
79
+ rescue EOFError
80
+ @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
81
+ end
75
82
  end
76
83
  end
77
84
 
@@ -81,7 +88,8 @@ class Distributor::Client
81
88
  data = io.readpartial(4096)
82
89
  @multiplexer.output ch, data
83
90
  rescue EOFError
84
- @processes.each { |ch| @multiplexer.close(ch) }
91
+ @on_close[ch].each { |c| p c; c.call(ch) }
92
+ @connector.close(io)
85
93
  end
86
94
  end
87
95
  end
@@ -90,6 +98,10 @@ class Distributor::Client
90
98
  @on_close[ch] << blk
91
99
  end
92
100
 
101
+ def on_hello(&blk)
102
+ @on_hello << blk
103
+ end
104
+
93
105
  def start
94
106
  loop { @connector.listen }
95
107
  end
@@ -6,10 +6,11 @@ class Distributor::Connector
6
6
 
7
7
  def initialize
8
8
  @connections = {}
9
- @on_close = Hash.new([])
9
+ @on_close = Hash.new { |hash,key| hash[key] = Array.new }
10
10
  end
11
11
 
12
12
  def handle(from, &handler)
13
+ return unless from
13
14
  @connections[from] = handler
14
15
  end
15
16
 
@@ -18,17 +19,19 @@ class Distributor::Connector
18
19
  end
19
20
 
20
21
  def listen
21
- rs, ws = IO.select(@connections.keys)
22
- rs.each do |from|
23
- @on_close.each { |c| c.call(from) } if from.eof?
24
- self.connections[from].call(from)
22
+ rs, ws = IO.select(@connections.keys, [], [], 1)
23
+ (rs || []).each do |from|
24
+ begin
25
+ @on_close[from].each { |c| c.call(from) } if from.eof?
26
+ @connections[from].call(from)
27
+ rescue Errno::EIO
28
+ end
25
29
  end
26
30
  end
27
31
 
28
32
  def close(io)
29
33
  @connections.delete(io)
30
34
  @on_close[io].each { |c| c.call(io) }
31
- exit 1
32
35
  end
33
36
 
34
37
  end
@@ -31,11 +31,11 @@ class Distributor::Multiplexer
31
31
  return if ch.nil?
32
32
  writer(ch).write data
33
33
  rescue IOError
34
- @output.write Distributor::Packet.create(0, JSON.dump({ "command" => "close", "ch" => ch }))
34
+ output 0, JSON.dump({ "command" => "close", "ch" => ch })
35
35
  end
36
36
 
37
37
  def output(ch, data)
38
- @output.write Distributor::Packet.create(ch, data)
38
+ Distributor::Packet.write(@output, ch, data)
39
39
  rescue Errno::EPIPE
40
40
  end
41
41
 
@@ -1,15 +1,22 @@
1
1
  require "distributor"
2
+ require "stringio"
3
+ require "thread"
2
4
 
3
5
  class Distributor::Packet
4
6
 
5
7
  PROTOCOL_VERSION = 1
6
8
 
7
- def self.create(channel, data)
8
- packet = "DIST"
9
- packet += pack(PROTOCOL_VERSION)
10
- packet += pack(channel)
11
- packet += pack(data.length)
12
- packet += data
9
+ def self.write(io, channel, data)
10
+ @@output ||= Mutex.new
11
+ @@output.synchronize do
12
+ buffer = StringIO.new
13
+ buffer.write "DIST"
14
+ buffer.write pack(PROTOCOL_VERSION)
15
+ buffer.write pack(channel)
16
+ buffer.write pack(data.length)
17
+ buffer.write data
18
+ io.write buffer.string
19
+ end
13
20
  end
14
21
 
15
22
  def self.parse(io)
@@ -1,6 +1,7 @@
1
1
  require "distributor"
2
2
  require "distributor/connector"
3
3
  require "distributor/multiplexer"
4
+ require "json"
4
5
  require "pty"
5
6
  require "socket"
6
7
 
@@ -18,7 +19,7 @@ class Distributor::Server
18
19
  @multiplexer.input io
19
20
  end
20
21
 
21
- @connector.on_close(input) do |ch|
22
+ @connector.on_close(input) do |io|
22
23
  exit 0
23
24
  end
24
25
 
@@ -29,8 +30,9 @@ class Distributor::Server
29
30
  dequeue_json do |data|
30
31
  case command = data["command"]
31
32
  when "tunnel" then
32
- ch = tunnel(data["port"])
33
- @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "ack", "ch" => ch })
33
+ port = (data["port"] || ENV["PORT"] || 5000).to_i
34
+ ch = tunnel(port)
35
+ @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "ack", "ch" => ch, "port" => port })
34
36
  when "close" then
35
37
  @multiplexer.close data["ch"]
36
38
  when "run" then
@@ -91,6 +93,7 @@ class Distributor::Server
91
93
  ch
92
94
  end
93
95
  def start
96
+ @multiplexer.output 0, JSON.dump({ "command" => "hello" })
94
97
  loop { @connector.listen }
95
98
  end
96
99
 
@@ -1,5 +1,5 @@
1
1
  module Distributor
2
2
 
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
 
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: distributor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-14 00:00:00.000000000 Z
12
+ date: 2012-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70255347061300 !ruby/object:Gem::Requirement
16
+ requirement: &70208946341240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 0.13.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70255347061300
24
+ version_requirements: *70208946341240
25
25
  description: TCP Multiplexer
26
26
  email: ddollar@gmail.com
27
27
  executables: []