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