anycable-core 1.1.0.pre1 → 1.1.0.rc1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f3906d5bd75c90a70af60b0ce10ab49c5940bc7818aa90f4e2af61831b9d5f2
4
- data.tar.gz: 3a5b9eea11ea0769d5dcfebd8721c3cf0d6925b470d636f895c37e8da82818a4
3
+ metadata.gz: c11526237ea5ddebe636470d76c0bc736b4033bfa82eb11213768d7907cd9e29
4
+ data.tar.gz: c9c14c21b7e05ae5e48683270139a219e65879dc96424886ff4f38d0c5e4e4d6
5
5
  SHA512:
6
- metadata.gz: 116b8c9a943c5785773f4286115cb01955e188bcc45e9583986db08cbbc7c945817280217df07956d2ca3bc739ad95a1120b7f1bf7a19655b19c1cccd49d290a
7
- data.tar.gz: aacd6b3e0dda79471150f6305dde49ec1efafdc05fae3c4e9da7ccaf1fa9dfb9c1d7554ac3154e74104b99807f2400f0da465f53da2dcd283870715609384e3f
6
+ metadata.gz: 35ddc978f4af9c962dfd08ce3c91d7baaa9396aaaf6305bf0b53c09b9bdebe66d3ee6c574d4c634b76100b853aa1e69256abadd1eb00e15bc28c113a02c02cd4
7
+ data.tar.gz: 3e44584b899e7a4041caf345a4a96b6791a52aad83af18f6c59ae11b450446d5bb40d816d917d6791d110c045c894302db9e9668c6f25252269eaf258e5d5231
data/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## master
4
4
 
5
- ## 1.1.0-dev
5
+ ## 1.1.0.rc1
6
6
 
7
7
  - **BREAKING** Move middlewares from gRPC interceptors to custom implementation. ([@palkan][])
8
8
 
@@ -12,7 +12,7 @@ The API changed a bit:
12
12
  ```diff
13
13
  class SomeMiddleware < AnyCable::Middleware
14
14
  - def call(request, rpc_call, rpc_handler)
15
- + def call(rpc_method_name, request)
15
+ + def call(rpc_method_name, request, metadata)
16
16
  yield
17
17
  end
18
18
  end
data/lib/anycable.rb CHANGED
@@ -9,6 +9,7 @@ require "anycable/broadcast_adapters"
9
9
 
10
10
  require "anycable/middleware_chain"
11
11
  require "anycable/middlewares/exceptions"
12
+ require "anycable/middlewares/check_version"
12
13
 
13
14
  require "anycable/socket"
14
15
  require "anycable/rpc"
data/lib/anycable/cli.rb CHANGED
@@ -19,6 +19,14 @@ module AnyCable
19
19
  # Wait for external process termination (s)
20
20
  WAIT_PROCESS = 2
21
21
 
22
+ # Run CLI inside the current process and shutdown at exit
23
+ def self.embed!(args = [])
24
+ new(embedded: true).tap do |cli|
25
+ cli.run(args)
26
+ at_exit { cli.shutdown }
27
+ end
28
+ end
29
+
22
30
  attr_reader :server, :health_server, :embedded
23
31
  alias_method :embedded?, :embedded
24
32
 
@@ -55,6 +63,8 @@ module AnyCable
55
63
 
56
64
  verify_server_builder!
57
65
 
66
+ check_version!
67
+
58
68
  @server = AnyCable.server_builder.call(config)
59
69
 
60
70
  # Make sure middlewares are not adding after server has started
@@ -247,6 +257,14 @@ module AnyCable
247
257
  exit(1)
248
258
  end
249
259
 
260
+ def check_version!
261
+ return unless config.version_check_enabled?
262
+
263
+ AnyCable.middleware.use(
264
+ AnyCable::Middlewares::CheckVersion.new(AnyCable::PROTO_VERSION)
265
+ )
266
+ end
267
+
250
268
  def parse_gem_options!(args)
251
269
  config.parse_options!(args)
252
270
  rescue OptionParser::InvalidOption => e
data/lib/anycable/grpc.rb CHANGED
@@ -9,22 +9,14 @@ end
9
9
 
10
10
  require "anycable/grpc/config"
11
11
  require "anycable/grpc/server"
12
- require "anycable/grpc/check_version"
13
12
 
14
13
  AnyCable.server_builder = ->(config) {
15
14
  AnyCable.logger.info "gRPC version: #{::GRPC::VERSION}"
16
15
 
17
16
  ::GRPC.define_singleton_method(:logger) { AnyCable.logger } if config.log_grpc?
18
17
 
19
- interceptors = []
20
-
21
- if config.version_check_enabled?
22
- interceptors << AnyCable::GRPC::CheckVersion.new(AnyCable::PROTO_VERSION)
23
- end
24
-
25
18
  params = config.to_grpc_params
26
19
  params[:host] = config.rpc_host
27
- params[:interceptors] = interceptors
28
20
 
29
21
  AnyCable::GRPC::Server.new(**params)
30
22
  }
@@ -9,16 +9,16 @@ module AnyCable
9
9
  # RPC service handler
10
10
  class Handler < AnyCable::GRPC::Service
11
11
  # Handle connection request from WebSocket server
12
- def connect(request, _unused_call)
13
- AnyCable.rpc_handler.handle(:connect, request)
12
+ def connect(request, call)
13
+ AnyCable.rpc_handler.handle(:connect, request, call.metadata)
14
14
  end
15
15
 
16
- def disconnect(request, _unused_call)
17
- AnyCable.rpc_handler.handle(:disconnect, request)
16
+ def disconnect(request, call)
17
+ AnyCable.rpc_handler.handle(:disconnect, request, call.metadata)
18
18
  end
19
19
 
20
- def command(request, _unused_call)
21
- AnyCable.rpc_handler.handle(:command, request)
20
+ def command(request, call)
21
+ AnyCable.rpc_handler.handle(:command, request, call.metadata)
22
22
  end
23
23
  end
24
24
  end
@@ -3,7 +3,7 @@
3
3
  module AnyCable
4
4
  # Middleware is an analague of Rack middlewares but for AnyCable RPC calls
5
5
  class Middleware
6
- def call(_method_name, _request)
6
+ def call(_method_name, _request, _meta)
7
7
  raise NotImplementedError
8
8
  end
9
9
  end
@@ -30,19 +30,19 @@ module AnyCable
30
30
  registry
31
31
  end
32
32
 
33
- def call(method_name, request, &block)
34
- return yield(method_name, request) if registry.none?
33
+ def call(method_name, request, meta = {}, &block)
34
+ return yield(method_name, request, meta) if registry.none?
35
35
 
36
- execute_next_middleware(0, method_name, request, block)
36
+ execute_next_middleware(0, method_name, request, meta, block)
37
37
  end
38
38
 
39
39
  private
40
40
 
41
- def execute_next_middleware(ind, method_name, request, block)
42
- return block.call(method_name, request) if ind >= registry.size
41
+ def execute_next_middleware(ind, method_name, request, meta, block)
42
+ return block.call(method_name, request, meta) if ind >= registry.size
43
43
 
44
- registry[ind].call(method_name, request) do
45
- execute_next_middleware(ind + 1, method_name, request, block)
44
+ registry[ind].call(method_name, request, meta) do
45
+ execute_next_middleware(ind + 1, method_name, request, meta, block)
46
46
  end
47
47
  end
48
48
 
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCable
4
+ module Middlewares
5
+ # Checks that RPC client version is compatible with
6
+ # the current RPC proto version
7
+ class CheckVersion < AnyCable::Middleware
8
+ attr_reader :version
9
+
10
+ def initialize(version)
11
+ @version = version
12
+ end
13
+
14
+ def call(_method, _request, meta)
15
+ check_version(meta) do
16
+ yield
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def check_version(metadata)
23
+ supported_versions = metadata["protov"]&.split(",")
24
+ return yield if supported_versions&.include?(version)
25
+
26
+ raise "Incompatible AnyCable RPC client.\nCurrent server version: #{version}.\n" \
27
+ "Client supported versions: #{metadata["protov"] || "unknown"}."
28
+ end
29
+ end
30
+ end
31
+ end
@@ -3,7 +3,7 @@
3
3
  module AnyCable
4
4
  module Middlewares
5
5
  class Exceptions < AnyCable::Middleware
6
- def call(method_name, request)
6
+ def call(method_name, request, _meta)
7
7
  yield
8
8
  rescue => exp
9
9
  notify_exception(exp, method_name, request)
@@ -16,8 +16,8 @@ module AnyCable
16
16
 
17
17
  private
18
18
 
19
- def notify_exception(exp, method_name, message)
20
- AnyCable::ExceptionsHandling.notify(exp, method_name.to_s, message.to_h)
19
+ def notify_exception(exp, method_name, request)
20
+ AnyCable::ExceptionsHandling.notify(exp, method_name.to_s, request.to_h)
21
21
  end
22
22
 
23
23
  def response_class(method_name)
@@ -17,8 +17,8 @@ module AnyCable
17
17
  @commands = {}
18
18
  end
19
19
 
20
- def handle(cmd, data)
21
- middleware.call(cmd, data) do
20
+ def handle(cmd, data, meta = {})
21
+ middleware.call(cmd, data, meta) do
22
22
  send(cmd, data)
23
23
  end
24
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnyCable
4
- VERSION = "1.1.0.pre1"
4
+ VERSION = "1.1.0.rc1"
5
5
  end
data/sig/anycable/cli.rbs CHANGED
@@ -8,6 +8,7 @@ module AnyCable
8
8
 
9
9
  alias embedded? embedded
10
10
 
11
+ def self.embed!: (Array[String]?) -> void
11
12
  def initialize: (?embedded: bool embedded) -> void
12
13
  def run: (?untyped args) -> void
13
14
  def shutdown: () -> void
@@ -1,5 +1,5 @@
1
1
  module AnyCable
2
2
  class Middleware
3
- def call: (Symbol, rpcRequest) { (Symbol, rpcRequest) -> rpcResponse } -> rpcResponse
3
+ def call: (Symbol, rpcRequest, rpcMetadata) { (Symbol, rpcRequest, rpcMetadata) -> rpcResponse } -> rpcResponse
4
4
  end
5
5
  end
@@ -1,16 +1,16 @@
1
1
  module AnyCable
2
2
  class MiddlewareChain
3
- type rpcHandlerBlock = ^(Symbol, rpcRequest) -> rpcResponse
3
+ type rpcHandlerBlock = ^(Symbol, rpcRequest, rpcMetadata) -> rpcResponse
4
4
 
5
5
  def initialize: () -> void
6
6
  def use: (singleton(Middleware) | Middleware middleware) -> void
7
7
  def freeze: () -> void
8
8
  def to_a: () -> Array[Middleware]
9
- def call: (Symbol, rpcRequest) { (Symbol, rpcRequest) -> rpcResponse } -> rpcResponse
9
+ def call: (Symbol, rpcRequest, ?rpcMetadata) { (Symbol, rpcRequest, rpcMetadata) -> rpcResponse } -> rpcResponse
10
10
 
11
11
  private
12
12
 
13
- def execute_next_middleware: (Integer ind, Symbol, rpcRequest, rpcHandlerBlock block) -> rpcResponse
13
+ def execute_next_middleware: (Integer ind, Symbol, rpcRequest, rpcMetadata, rpcHandlerBlock block) -> rpcResponse
14
14
 
15
15
  attr_reader mu: untyped
16
16
  attr_reader registry: Array[Middleware]
data/sig/anycable/rpc.rbs CHANGED
@@ -4,6 +4,7 @@ module AnyCable
4
4
 
5
5
  type rpcStatus = 0 | 1 | 2
6
6
  type protoMap = Hash[String, String]
7
+ type rpcMetadata = Hash[String, String]
7
8
 
8
9
  interface _WithEnvState
9
10
  def cstate: () -> protoMap?
@@ -60,6 +61,7 @@ module AnyCable
60
61
  include _WithEnv
61
62
 
62
63
  def initialize: (?env: Env) -> void
64
+ def to_h: () -> Hash[String, untyped]
63
65
  end
64
66
 
65
67
  class ConnectionResponse
@@ -78,6 +80,8 @@ module AnyCable
78
80
  ?error_msg: String,
79
81
  ?env: EnvResponse
80
82
  ) -> void
83
+
84
+ def to_h: () -> Hash[String, untyped]
81
85
  end
82
86
 
83
87
  class CommandMessage
@@ -94,6 +98,8 @@ module AnyCable
94
98
  ?connection_identifiers: String,
95
99
  ?env: Env
96
100
  ) -> void
101
+
102
+ def to_h: () -> Hash[String, untyped]
97
103
  end
98
104
 
99
105
  class CommandResponse
@@ -118,6 +124,8 @@ module AnyCable
118
124
  ?error_msg: String,
119
125
  ?env: EnvResponse
120
126
  ) -> void
127
+
128
+ def to_h: () -> Hash[String, untyped]
121
129
  end
122
130
 
123
131
  class DisconnectRequest
@@ -127,6 +135,7 @@ module AnyCable
127
135
  attr_accessor subscriptions: Array[String]
128
136
 
129
137
  def initialize: (identifiers: String, ?subscriptions: Array[String], ?env: Env) -> void
138
+ def to_h: () -> Hash[String, untyped]
130
139
  end
131
140
 
132
141
  class DisconnectResponse
@@ -136,6 +145,7 @@ module AnyCable
136
145
  attr_accessor error_msg: String?
137
146
 
138
147
  def initialize: (status: rpcStatus, ?error_msg: String) -> void
148
+ def to_h: () -> Hash[String, untyped]
139
149
  end
140
150
 
141
151
  type rpcRequest = ConnectionRequest | DisconnectRequest | CommandMessage
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anycable-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.pre1
4
+ version: 1.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-28 00:00:00.000000000 Z
11
+ date: 2021-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -176,7 +176,6 @@ files:
176
176
  - lib/anycable/config.rb
177
177
  - lib/anycable/exceptions_handling.rb
178
178
  - lib/anycable/grpc.rb
179
- - lib/anycable/grpc/check_version.rb
180
179
  - lib/anycable/grpc/config.rb
181
180
  - lib/anycable/grpc/handler.rb
182
181
  - lib/anycable/grpc/rpc_services_pb.rb
@@ -184,6 +183,7 @@ files:
184
183
  - lib/anycable/health_server.rb
185
184
  - lib/anycable/middleware.rb
186
185
  - lib/anycable/middleware_chain.rb
186
+ - lib/anycable/middlewares/check_version.rb
187
187
  - lib/anycable/middlewares/exceptions.rb
188
188
  - lib/anycable/protos/rpc_pb.rb
189
189
  - lib/anycable/rpc.rb
@@ -215,6 +215,7 @@ metadata:
215
215
  documentation_uri: https://docs.anycable.io/
216
216
  homepage_uri: https://anycable.io/
217
217
  source_code_uri: http://github.com/anycable/anycable
218
+ funding_uri: https://github.com/sponsors/anycable
218
219
  post_install_message:
219
220
  rdoc_options: []
220
221
  require_paths:
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnyCable
4
- module GRPC
5
- # Checks that gRPC client version is compatible with
6
- # the current RPC proto version
7
- class CheckVersion < ::GRPC::ServerInterceptor
8
- attr_reader :version
9
-
10
- def initialize(version)
11
- @version = version
12
- end
13
-
14
- def request_response(request: nil, call: nil, method: nil)
15
- # Call only for AnyCable service
16
- return yield unless method.receiver.is_a?(AnyCable::GRPC::Handler)
17
-
18
- check_version(call) do
19
- yield
20
- end
21
- end
22
-
23
- def check_version(call)
24
- supported_versions = call.metadata["protov"]&.split(",")
25
- return yield if supported_versions&.include?(version)
26
-
27
- raise ::GRPC::Internal,
28
- "Incompatible AnyCable RPC client.\nCurrent server version: #{version}.\n" \
29
- "Client supported versions: #{call.metadata["protov"] || "unknown"}."
30
- end
31
- end
32
- end
33
- end