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.
- data/lib/distributor/client.rb +46 -19
- data/lib/distributor/connector.rb +7 -1
- data/lib/distributor/multiplexer.rb +1 -1
- data/lib/distributor/server.rb +58 -13
- data/lib/distributor/version.rb +1 -1
- metadata +3 -3
data/lib/distributor/client.rb
CHANGED
@@ -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
|
-
|
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
27
|
|
27
28
|
# handle the command channel of the multiplexer
|
28
29
|
@connector.handle(@multiplexer.reader(0)) do |io|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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 =
|
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
|
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
|
data/lib/distributor/server.rb
CHANGED
@@ -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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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.
|
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
|
60
|
-
|
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
|
data/lib/distributor/version.rb
CHANGED
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
|
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: &
|
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: *
|
24
|
+
version_requirements: *70208191262780
|
25
25
|
description: TCP Multiplexer
|
26
26
|
email: ddollar@gmail.com
|
27
27
|
executables: []
|