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.
@@ -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 = true
31
+ @_close_handlers = []
32
+ @_error_handlers = []
33
+ @_active = true
23
34
  end
24
35
 
25
- def transmit(data, type: :text)
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 IOError, Errno::EPIPE, Errno::ETIMEDOUT => e
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
- begin
66
- handler.call(data)
67
- rescue => e # rubocop: disable Style/RescueStandardError
68
- log(:error, "Socket receive failed: #{e}")
69
- @_error_handlers.each { |eh| eh.call(e, data) }
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 IOError, Errno::EPIPE, Errno::ETIMEDOUT
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
- time = Time.now.to_i
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 Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ECONNRESET, IOError, Errno::EBADF => e
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AnyCable
4
4
  module Rack
5
- VERSION = "0.1.0"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  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.1.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yulia Oletskaya
8
- autorequire:
8
+ - Vladimir Dementyev
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2019-01-14 00:00:00.000000000 Z
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: '0.6'
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.6'
47
+ version: '2.0'
27
48
  - !ruby/object:Gem::Dependency
28
- name: websocket
49
+ name: connection_pool
29
50
  requirement: !ruby/object:Gem::Requirement
30
51
  requirements:
31
52
  - - "~>"
32
53
  - !ruby/object:Gem::Version
33
- version: '1.2'
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: '1.2'
61
+ version: '2.2'
41
62
  - !ruby/object:Gem::Dependency
42
- name: redis
63
+ name: websocket
43
64
  requirement: !ruby/object:Gem::Requirement
44
65
  requirements:
45
66
  - - "~>"
46
67
  - !ruby/object:Gem::Version
47
- version: '4'
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: '4'
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.8.4
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.8.4
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: '12.3'
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: '12.3'
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.60.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.60.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
- rubyforge_project:
169
- rubygems_version: 2.7.6
170
- signing_key:
206
+ rubygems_version: 3.2.15
207
+ signing_key:
171
208
  specification_version: 4
172
- summary: Anycable Rack Server
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