distributor 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []