distributor 0.0.1 → 0.1.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.
@@ -20,26 +20,29 @@ class Distributor::Client
20
20
  @multiplexer.input io
21
21
  end
22
22
 
23
- @connector.on_close(input) do |io|
24
- @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
25
- end
23
+ # @connector.on_close(input) do |io|
24
+ # p [:cl1, input]
25
+ # @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
26
+ # end
26
27
 
27
28
  # handle the command channel of the multiplexer
28
29
  @connector.handle(@multiplexer.reader(0)) do |io|
29
- data = JSON.parse(io.readpartial(4096))
30
-
31
- case command = data["command"]
32
- when "close" then
33
- ch = data["ch"]
34
- @on_close[ch].each { |c| c.call(ch) }
35
- when "launch" then
36
- ch = data["ch"]
37
- @multiplexer.reserve ch
38
- @handlers[data["id"]].call(ch)
39
- @handlers.delete(data["id"])
40
- @processes << ch
41
- else
42
- raise "no such command: #{command}"
30
+ append_json(io.readpartial(4096))
31
+
32
+ dequeue_json do |data|
33
+ case command = data["command"]
34
+ when "close" then
35
+ ch = data["ch"]
36
+ @on_close[ch].each { |c| c.call(ch) }
37
+ when "ack" then
38
+ ch = data["ch"]
39
+ @multiplexer.reserve ch
40
+ @handlers[data["id"]].call(ch)
41
+ @handlers.delete(data["id"])
42
+ @processes << ch
43
+ else
44
+ raise "no such command: #{command}"
45
+ end
43
46
  end
44
47
  end
45
48
  end
@@ -49,12 +52,18 @@ class Distributor::Client
49
52
  end
50
53
 
51
54
  def run(command, &handler)
52
- id = "#{Time.now.to_f}-#{rand(10000)}"
55
+ id = generate_id
53
56
  @multiplexer.output 0, JSON.dump({ "id" => id, "command" => "run", "args" => command })
54
57
  @handlers[id] = handler
55
58
  end
56
59
 
57
- def hookup(ch, input, output)
60
+ def tunnel(port, &handler)
61
+ id = generate_id
62
+ @multiplexer.output 0, JSON.dump({ "id" => id, "command" => "tunnel", "port" => port })
63
+ @handlers[id] = handler
64
+ end
65
+
66
+ def hookup(ch, input, output=input)
58
67
  # handle data incoming on the multiplexer
59
68
  @connector.handle(@multiplexer.reader(ch)) do |io|
60
69
  begin
@@ -85,4 +94,22 @@ class Distributor::Client
85
94
  loop { @connector.listen }
86
95
  end
87
96
 
97
+ private
98
+
99
+ def generate_id
100
+ id = "#{Time.now.to_f}-#{rand(10000)}"
101
+ end
102
+
103
+ def append_json(data)
104
+ @json ||= ""
105
+ @json += data
106
+ end
107
+
108
+ def dequeue_json
109
+ while idx = @json.index("}")
110
+ yield JSON.parse(@json[0..idx])
111
+ @json = @json[idx+1..-1]
112
+ end
113
+ end
114
+
88
115
  end
@@ -20,9 +20,15 @@ class Distributor::Connector
20
20
  def listen
21
21
  rs, ws = IO.select(@connections.keys)
22
22
  rs.each do |from|
23
- @on_close.each { |c| c.call } if from.eof?
23
+ @on_close.each { |c| c.call(from) } if from.eof?
24
24
  self.connections[from].call(from)
25
25
  end
26
26
  end
27
27
 
28
+ def close(io)
29
+ @connections.delete(io)
30
+ @on_close[io].each { |c| c.call(io) }
31
+ exit 1
32
+ end
33
+
28
34
  end
@@ -40,7 +40,7 @@ class Distributor::Multiplexer
40
40
  end
41
41
 
42
42
  def close(ch)
43
- writer(ch).close
43
+ output 0, JSON.dump({ "command" => "close", "ch" => ch })
44
44
  rescue IOError
45
45
  end
46
46
 
@@ -2,6 +2,7 @@ require "distributor"
2
2
  require "distributor/connector"
3
3
  require "distributor/multiplexer"
4
4
  require "pty"
5
+ require "socket"
5
6
 
6
7
  class Distributor::Server
7
8
 
@@ -17,18 +18,27 @@ class Distributor::Server
17
18
  @multiplexer.input io
18
19
  end
19
20
 
21
+ @connector.on_close(input) do |ch|
22
+ exit 0
23
+ end
24
+
20
25
  # handle the command channel of the multiplexer
21
26
  @connector.handle(@multiplexer.reader(0)) do |io|
22
- data = JSON.parse(io.readpartial(4096))
23
-
24
- case command = data["command"]
25
- when "close" then
26
- @multiplexer.close data["ch"]
27
- when "run" then
28
- ch = run(data["args"])
29
- @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "launch", "ch" => ch })
30
- else
31
- raise "no such command: #{command}"
27
+ append_json(io.readpartial(4096))
28
+
29
+ dequeue_json do |data|
30
+ case command = data["command"]
31
+ when "tunnel" then
32
+ ch = tunnel(data["port"])
33
+ @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "ack", "ch" => ch })
34
+ when "close" then
35
+ @multiplexer.close data["ch"]
36
+ when "run" then
37
+ ch = run(data["args"])
38
+ @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "ack", "ch" => ch })
39
+ else
40
+ raise "no such command: #{command}"
41
+ end
32
42
  end
33
43
  end
34
44
  end
@@ -43,7 +53,8 @@ class Distributor::Server
43
53
  begin
44
54
  @multiplexer.output(ch, io.readpartial(4096))
45
55
  rescue EOFError
46
- @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
56
+ @multiplexer.close(ch)
57
+ @connector.close(io)
47
58
  end
48
59
  end
49
60
 
@@ -56,11 +67,45 @@ class Distributor::Server
56
67
  ch
57
68
  end
58
69
 
59
- def close(ch)
60
- end
70
+ def tunnel(port)
71
+ ch = @multiplexer.reserve
72
+
73
+ tcp = TCPSocket.new("localhost", port)
74
+
75
+ # handle data incoming from process
76
+ @connector.handle(tcp) do |io|
77
+ begin
78
+ @multiplexer.output(ch, io.readpartial(4096))
79
+ rescue EOFError
80
+ @multiplexer.close(ch)
81
+ @connector.close(io)
82
+ end
83
+ end
61
84
 
85
+ # handle data incoming on the multiplexer
86
+ @connector.handle(@multiplexer.reader(ch)) do |input_io|
87
+ data = input_io.readpartial(4096)
88
+ tcp.write data
89
+ end
90
+
91
+ ch
92
+ end
62
93
  def start
63
94
  loop { @connector.listen }
64
95
  end
65
96
 
97
+ private
98
+
99
+ def append_json(data)
100
+ @json ||= ""
101
+ @json += data
102
+ end
103
+
104
+ def dequeue_json
105
+ while idx = @json.index("}")
106
+ yield JSON.parse(@json[0..idx])
107
+ @json = @json[idx+1..-1]
108
+ end
109
+ end
110
+
66
111
  end
@@ -1,5 +1,5 @@
1
1
  module Distributor
2
2
 
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.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.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-06-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70336779621500 !ruby/object:Gem::Requirement
16
+ requirement: &70208191262780 !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: *70336779621500
24
+ version_requirements: *70208191262780
25
25
  description: TCP Multiplexer
26
26
  email: ddollar@gmail.com
27
27
  executables: []