anycable-rack-server 0.1.0 → 0.4.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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +63 -26
- data/lib/anycable-rack-server.rb +13 -0
- data/lib/anycable/rack/broadcast_subscribers/base_subscriber.rb +41 -0
- data/lib/anycable/rack/broadcast_subscribers/http_subscriber.rb +44 -0
- data/lib/anycable/rack/broadcast_subscribers/redis_subscriber.rb +34 -19
- data/lib/anycable/rack/coders/json.rb +1 -1
- data/lib/anycable/rack/coders/msgpack.rb +22 -0
- data/lib/anycable/rack/config.rb +22 -0
- data/lib/anycable/rack/connection.rb +36 -21
- data/lib/anycable/rack/hub.rb +32 -1
- data/lib/anycable/rack/middleware.rb +15 -15
- data/lib/anycable/rack/pinger.rb +5 -2
- data/lib/anycable/rack/railtie.rb +6 -30
- data/lib/anycable/rack/rpc/client.rb +41 -14
- data/lib/anycable/rack/rpc/rpc.proto +18 -4
- data/lib/anycable/rack/server.rb +63 -36
- data/lib/anycable/rack/socket.rb +29 -19
- data/lib/anycable/rack/version.rb +1 -1
- metadata +67 -30
- data/lib/anycable/rack/rpc_runner.rb +0 -60
data/lib/anycable/rack/socket.rb
CHANGED
@@ -4,6 +4,17 @@ require "anycable/rack/logging"
|
|
4
4
|
|
5
5
|
module AnyCable
|
6
6
|
module Rack
|
7
|
+
# Wrapper for outgoing data used to correctly set the WS frame type
|
8
|
+
class BinaryFrame
|
9
|
+
def initialize(data)
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
@data.to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
7
18
|
# Socket wrapper
|
8
19
|
class Socket
|
9
20
|
include Logging
|
@@ -15,21 +26,23 @@ module AnyCable
|
|
15
26
|
@socket = socket
|
16
27
|
@version = version
|
17
28
|
|
18
|
-
@_open_handlers
|
29
|
+
@_open_handlers = []
|
19
30
|
@_message_handlers = []
|
20
|
-
@_close_handlers
|
21
|
-
@_error_handlers
|
22
|
-
@_active
|
31
|
+
@_close_handlers = []
|
32
|
+
@_error_handlers = []
|
33
|
+
@_active = true
|
23
34
|
end
|
24
35
|
|
25
|
-
def transmit(data, type:
|
36
|
+
def transmit(data, type: nil)
|
37
|
+
# p "DATA: #{data.class} — #{data.to_s}"
|
38
|
+
type ||= data.is_a?(BinaryFrame) ? :binary : :text
|
26
39
|
frame = WebSocket::Frame::Outgoing::Server.new(
|
27
40
|
version: version,
|
28
41
|
data: data,
|
29
42
|
type: type
|
30
43
|
)
|
31
44
|
socket.write(frame.to_s)
|
32
|
-
rescue
|
45
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
33
46
|
log(:error, "Socket send failed: #{e}")
|
34
47
|
close
|
35
48
|
end
|
@@ -62,13 +75,11 @@ module AnyCable
|
|
62
75
|
@_open_handlers.each(&:call)
|
63
76
|
each_frame do |data|
|
64
77
|
@_message_handlers.each do |handler|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
close
|
71
|
-
end
|
78
|
+
handler.call(data)
|
79
|
+
rescue => e # rubocop: disable Style/RescueStandardError
|
80
|
+
log(:error, "Socket receive failed: #{e}")
|
81
|
+
@_error_handlers.each { |eh| eh.call(e, data) }
|
82
|
+
close
|
72
83
|
end
|
73
84
|
end
|
74
85
|
ensure
|
@@ -104,7 +115,7 @@ module AnyCable
|
|
104
115
|
frame = WebSocket::Frame::Outgoing::Server.new(version: version, type: :close, code: 1000)
|
105
116
|
socket.write(frame.to_s) if frame.supported?
|
106
117
|
socket.close
|
107
|
-
rescue
|
118
|
+
rescue Exception # rubocop:disable Lint/RescueException
|
108
119
|
# already closed
|
109
120
|
end
|
110
121
|
|
@@ -113,8 +124,7 @@ module AnyCable
|
|
113
124
|
Thread.current.abort_on_exception = true
|
114
125
|
loop do
|
115
126
|
sleep 5
|
116
|
-
|
117
|
-
transmit({ message: time, type: :ping }.to_json)
|
127
|
+
transmit nil, type: :ping
|
118
128
|
end
|
119
129
|
end
|
120
130
|
|
@@ -137,7 +147,7 @@ module AnyCable
|
|
137
147
|
|
138
148
|
framebuffer << data
|
139
149
|
|
140
|
-
while frame = framebuffer.next
|
150
|
+
while frame = framebuffer.next # rubocop:disable Lint/AssignmentInCondition
|
141
151
|
case frame.type
|
142
152
|
when :close
|
143
153
|
return
|
@@ -146,8 +156,8 @@ module AnyCable
|
|
146
156
|
end
|
147
157
|
end
|
148
158
|
end
|
149
|
-
rescue
|
150
|
-
log(:error, "Socket frame error: #{e}")
|
159
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
160
|
+
log(:error, "Socket frame error: #{e}\n #{e.backtrace.take(4).join("\n")}")
|
151
161
|
nil # client disconnected or timed out
|
152
162
|
end
|
153
163
|
end
|
metadata
CHANGED
@@ -1,71 +1,92 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anycable-rack-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yulia Oletskaya
|
8
|
-
|
8
|
+
- Vladimir Dementyev
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-05-14 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: anyway_config
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 2.1.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 2.1.0
|
13
28
|
- !ruby/object:Gem::Dependency
|
14
29
|
name: anycable
|
15
30
|
requirement: !ruby/object:Gem::Requirement
|
16
31
|
requirements:
|
17
|
-
- - "
|
32
|
+
- - ">"
|
18
33
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
34
|
+
version: 1.0.99
|
35
|
+
- - "<"
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.0'
|
20
38
|
type: :runtime
|
21
39
|
prerelease: false
|
22
40
|
version_requirements: !ruby/object:Gem::Requirement
|
23
41
|
requirements:
|
24
|
-
- - "
|
42
|
+
- - ">"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.0.99
|
45
|
+
- - "<"
|
25
46
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0
|
47
|
+
version: '2.0'
|
27
48
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
49
|
+
name: connection_pool
|
29
50
|
requirement: !ruby/object:Gem::Requirement
|
30
51
|
requirements:
|
31
52
|
- - "~>"
|
32
53
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
54
|
+
version: '2.2'
|
34
55
|
type: :runtime
|
35
56
|
prerelease: false
|
36
57
|
version_requirements: !ruby/object:Gem::Requirement
|
37
58
|
requirements:
|
38
59
|
- - "~>"
|
39
60
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
61
|
+
version: '2.2'
|
41
62
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
63
|
+
name: websocket
|
43
64
|
requirement: !ruby/object:Gem::Requirement
|
44
65
|
requirements:
|
45
66
|
- - "~>"
|
46
67
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
68
|
+
version: '1.2'
|
48
69
|
type: :runtime
|
49
70
|
prerelease: false
|
50
71
|
version_requirements: !ruby/object:Gem::Requirement
|
51
72
|
requirements:
|
52
73
|
- - "~>"
|
53
74
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
75
|
+
version: '1.2'
|
55
76
|
- !ruby/object:Gem::Dependency
|
56
77
|
name: anyt
|
57
78
|
requirement: !ruby/object:Gem::Requirement
|
58
79
|
requirements:
|
59
|
-
- - "
|
80
|
+
- - ">="
|
60
81
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
82
|
+
version: '0'
|
62
83
|
type: :development
|
63
84
|
prerelease: false
|
64
85
|
version_requirements: !ruby/object:Gem::Requirement
|
65
86
|
requirements:
|
66
|
-
- - "
|
87
|
+
- - ">="
|
67
88
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
89
|
+
version: '0'
|
69
90
|
- !ruby/object:Gem::Dependency
|
70
91
|
name: minitest
|
71
92
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,32 +117,46 @@ dependencies:
|
|
96
117
|
version: '0'
|
97
118
|
- !ruby/object:Gem::Dependency
|
98
119
|
name: rake
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '13.0'
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '13.0'
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: redis
|
99
134
|
requirement: !ruby/object:Gem::Requirement
|
100
135
|
requirements:
|
101
136
|
- - "~>"
|
102
137
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
138
|
+
version: '4'
|
104
139
|
type: :development
|
105
140
|
prerelease: false
|
106
141
|
version_requirements: !ruby/object:Gem::Requirement
|
107
142
|
requirements:
|
108
143
|
- - "~>"
|
109
144
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
145
|
+
version: '4'
|
111
146
|
- !ruby/object:Gem::Dependency
|
112
147
|
name: rubocop
|
113
148
|
requirement: !ruby/object:Gem::Requirement
|
114
149
|
requirements:
|
115
|
-
- - "
|
150
|
+
- - ">="
|
116
151
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
152
|
+
version: '0.80'
|
118
153
|
type: :development
|
119
154
|
prerelease: false
|
120
155
|
version_requirements: !ruby/object:Gem::Requirement
|
121
156
|
requirements:
|
122
|
-
- - "
|
157
|
+
- - ">="
|
123
158
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.
|
159
|
+
version: '0.80'
|
125
160
|
description: AnyCable-compatible Ruby Rack middleware
|
126
161
|
email: yulia.oletskaya@gmail.com
|
127
162
|
executables: []
|
@@ -131,8 +166,12 @@ files:
|
|
131
166
|
- LICENSE
|
132
167
|
- README.md
|
133
168
|
- lib/anycable-rack-server.rb
|
169
|
+
- lib/anycable/rack/broadcast_subscribers/base_subscriber.rb
|
170
|
+
- lib/anycable/rack/broadcast_subscribers/http_subscriber.rb
|
134
171
|
- lib/anycable/rack/broadcast_subscribers/redis_subscriber.rb
|
135
172
|
- lib/anycable/rack/coders/json.rb
|
173
|
+
- lib/anycable/rack/coders/msgpack.rb
|
174
|
+
- lib/anycable/rack/config.rb
|
136
175
|
- lib/anycable/rack/connection.rb
|
137
176
|
- lib/anycable/rack/errors.rb
|
138
177
|
- lib/anycable/rack/hub.rb
|
@@ -142,15 +181,14 @@ files:
|
|
142
181
|
- lib/anycable/rack/railtie.rb
|
143
182
|
- lib/anycable/rack/rpc/client.rb
|
144
183
|
- lib/anycable/rack/rpc/rpc.proto
|
145
|
-
- lib/anycable/rack/rpc_runner.rb
|
146
184
|
- lib/anycable/rack/server.rb
|
147
185
|
- lib/anycable/rack/socket.rb
|
148
186
|
- lib/anycable/rack/version.rb
|
149
|
-
homepage:
|
187
|
+
homepage:
|
150
188
|
licenses:
|
151
189
|
- MIT
|
152
190
|
metadata: {}
|
153
|
-
post_install_message:
|
191
|
+
post_install_message:
|
154
192
|
rdoc_options: []
|
155
193
|
require_paths:
|
156
194
|
- lib
|
@@ -165,9 +203,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
203
|
- !ruby/object:Gem::Version
|
166
204
|
version: '0'
|
167
205
|
requirements: []
|
168
|
-
|
169
|
-
|
170
|
-
signing_key:
|
206
|
+
rubygems_version: 3.2.15
|
207
|
+
signing_key:
|
171
208
|
specification_version: 4
|
172
|
-
summary:
|
209
|
+
summary: AnyCable Rack Server
|
173
210
|
test_files: []
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "anycable"
|
4
|
-
require "anycable/rack/logging"
|
5
|
-
|
6
|
-
$stdout.sync = true
|
7
|
-
|
8
|
-
module AnyCable
|
9
|
-
module Rack
|
10
|
-
# Runs AnyCable CLI in a separate process
|
11
|
-
module RPCRunner
|
12
|
-
class << self
|
13
|
-
include Logging
|
14
|
-
|
15
|
-
attr_accessor :running, :pid
|
16
|
-
|
17
|
-
def run(root_dir:, command_args: [], rpc_host: "[::]:50051", env: {})
|
18
|
-
return if @running
|
19
|
-
|
20
|
-
command_args << "--rpc-host=\"#{rpc_host}\""
|
21
|
-
|
22
|
-
command = "bundle exec anycable #{command_args.join(' ')}"
|
23
|
-
|
24
|
-
log(:info, "Running AnyCable (from #{root_dir}): #{command}")
|
25
|
-
|
26
|
-
out = AnyCable.config.debug? ? STDOUT : IO::NULL
|
27
|
-
|
28
|
-
@pid = Dir.chdir(root_dir) do
|
29
|
-
Process.spawn(
|
30
|
-
env,
|
31
|
-
command,
|
32
|
-
out: out,
|
33
|
-
err: out
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
log(:debug) { "AnyCable PID: #{pid}" }
|
38
|
-
|
39
|
-
@running = true
|
40
|
-
|
41
|
-
at_exit { stop }
|
42
|
-
end
|
43
|
-
|
44
|
-
def stop
|
45
|
-
return unless running
|
46
|
-
|
47
|
-
log(:debug) { "Terminate PID: #{pid}" }
|
48
|
-
|
49
|
-
Process.kill("SIGKILL", pid)
|
50
|
-
|
51
|
-
@running = false
|
52
|
-
end
|
53
|
-
|
54
|
-
def running?
|
55
|
-
running == true
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|