anycable-core 1.1.0.pre1 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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