anycable-core 1.2.5 → 1.3.0

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: 5e9ba8037b7cbd766d021b4e88d49101b6dc3e9a5a6b355929bf9aaa8494f33a
4
- data.tar.gz: 71cd40b2380601f322a335d774cfb41e39f8de6ac29f4b5201a825119bff1031
3
+ metadata.gz: 215d37d67fe10f536e6eb2a9b8ae5e53603d4653fb2034aff9abece234da7097
4
+ data.tar.gz: 50457dfd126925e875f3bb1ab323df90a0381f13de399f07e20a8cd4f2cab5d7
5
5
  SHA512:
6
- metadata.gz: f1a372e6d70eb1db64054aeafcc3baccd674d679652309526fbcfe9329799383b671d532cd16a52dd53b00b4a1658100d000f4564f2cbaac00502e02da00b668
7
- data.tar.gz: 5d9434268c8d7b3903544ab357caadcb69150be82d921c2de2916f4191b1280c0c3b981de285425d969bd1693b02974be4a844447576e3975ed0280c877be3c0
6
+ metadata.gz: 43eac0f870ba33726095d8801772d3b18dd2a909a937c9c03177aab163d2ee93f92979bcfcf4cb3eb2039e80e3f28ec123d9e215ee07fe4b87fb152510f7b87d
7
+ data.tar.gz: be1a5de79d480aa5d0b081354103f325cb3f997d8d134ba325b92d233408696236afedd600c7133ccb307ac7ceb9b16c60e284588942aa83886007384002a372
data/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.3.0 (2023-02-28)
6
+
7
+ - Add configuration presets. ([@palkan][])
8
+
9
+ Provide sensible defaults matching current platform (e.g., Fly.io).
10
+
11
+ - Require Ruby 2.7+ and Anyway Config 2.2+.
12
+
13
+ - Add `rpc_max_connection_age` option (if favour of `rpc_server_args.max_connection_age_ms`) and configured its **default value to be 300 (5 minutes)**. ([@palkan][])
14
+
15
+ - (_Experimental_) Add support for [grpc_kit](https://github.com/cookpad/grpc_kit) as an alternative gRPC implementation. ([@palkan][], [@cylon-v][])
16
+
17
+ Add `grpc_kit` to your Gemfile and specify `ANYCABLE_GRPC_IMPL=grpc_kit` env var to use it.
18
+
19
+ - Setting the redis driver to ruby specified. ([@smasry][])
20
+
21
+ - Add mutual TLS support for connections to Redis. ([@Envek][])
22
+
23
+ `ANYCABLE_REDIS_TLS_CLIENT_CERT_PATH` and `ANYCABLE_REDIS_TLS_CLIENT_KEY_PATH` settings to specify client certificate and key when connecting to Redis server that requires clients to authenticate themselves.
24
+
5
25
  ## 1.2.5 (2022-12-01)
6
26
 
7
27
  - Add `ANYCABLE_REDIS_TLS_VERIFY` setting to disable validation of Redis server TLS certificate. ([@Envek][])
@@ -132,7 +152,6 @@ See [#71](https://github.com/anycable/anycable/pull/71).
132
152
  See [Changelog](https://github.com/anycable/anycable/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
133
153
 
134
154
  [@palkan]: https://github.com/palkan
135
- [@sponomarev]: https://github.com/sponomarev
136
- [@bibendi]: https://github.com/bibendi
137
155
  [@smasry]: https://github.com/smasry
138
156
  [@Envek]: https://github.com/Envek
157
+ [@cylon-v]: https://github.com/cylon-v
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2017-2022 Vladimir Dementyev
1
+ Copyright 2017-2023 Vladimir Dementyev
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/anycable.svg)](https://rubygems.org/gems/anycable)
2
2
  [![Build](https://github.com/anycable/anycable/workflows/Build/badge.svg)](https://github.com/anycable/anycable/actions)
3
+ [![Coverage Status](https://coveralls.io/repos/github/anycable/anycable/badge.svg?branch=master)](https://coveralls.io/github/anycable/anycable?branch=master)
3
4
  [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io/v1)
4
5
 
5
6
  # AnyCable
@@ -18,8 +19,8 @@ AnyCable uses the same protocol as ActionCable, so you can use its [JavaScript c
18
19
 
19
20
  ## Requirements
20
21
 
21
- - Ruby >= 2.6
22
- - Redis (for broadcasting **in production**, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
22
+ - Ruby >= 2.7
23
+ - Redis or NATS (for broadcasting **in production**, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
23
24
 
24
25
  ## Usage
25
26
 
@@ -30,7 +30,7 @@ module AnyCable
30
30
  **options
31
31
  )
32
32
  options = AnyCable.config.to_redis_params.merge(options)
33
- options[:driver] = :ruby
33
+ options[:driver] ||= :ruby
34
34
  @redis_conn = ::Redis.new(**options)
35
35
  @channel = channel
36
36
  end
@@ -3,7 +3,7 @@
3
3
  require "anycable/broadcast_adapters/base"
4
4
 
5
5
  module AnyCable
6
- module BroadcastAdapters # :nodoc:
6
+ module BroadcastAdapters
7
7
  module_function
8
8
 
9
9
  def lookup_adapter(args)
data/lib/anycable/cli.rb CHANGED
@@ -333,7 +333,7 @@ module AnyCable
333
333
  $ anycable [options]
334
334
 
335
335
  CLI
336
- -r, --require=path Location of application file to require, default: "config/environment.rb"
336
+ -r, --require=path Location of application file to require, default candidates: #{APP_CANDIDATES.join(", ")}
337
337
  --server-command=command Command to run WebSocket server
338
338
  -v, --version Print version and exit
339
339
  -h, --help Show this help
@@ -21,6 +21,8 @@ module AnyCable
21
21
  config_name :anycable
22
22
 
23
23
  attr_config(
24
+ presets: "",
25
+
24
26
  ## PubSub
25
27
  broadcast_adapter: :redis,
26
28
 
@@ -29,6 +31,8 @@ module AnyCable
29
31
  redis_sentinels: nil,
30
32
  redis_channel: "__anycable__",
31
33
  redis_tls_verify: false,
34
+ redis_tls_client_cert_path: nil,
35
+ redis_tls_client_key_path: nil,
32
36
 
33
37
  ### NATS options
34
38
  nats_servers: "nats://localhost:4222",
@@ -54,23 +58,21 @@ module AnyCable
54
58
  sid_header_enabled: true
55
59
  )
56
60
 
57
- if respond_to?(:coerce_types)
58
- coerce_types(
59
- redis_sentinels: {type: nil, array: true},
60
- nats_servers: {type: nil, array: true},
61
- redis_tls_verify: :boolean,
62
- nats_dont_randomize_servers: :boolean,
63
- debug: :boolean,
64
- version_check_enabled: :boolean
65
- )
66
- end
61
+ coerce_types(
62
+ presets: {type: nil, array: true},
63
+ redis_sentinels: {type: nil, array: true},
64
+ nats_servers: {type: nil, array: true},
65
+ redis_tls_verify: :boolean,
66
+ nats_dont_randomize_servers: :boolean,
67
+ debug: :boolean,
68
+ version_check_enabled: :boolean
69
+ )
67
70
 
68
71
  flag_options :debug, :nats_dont_randomize_servers
69
72
  ignore_options :nats_options
70
73
 
71
- on_load do
72
- # @type self : AnyCable::Config
73
- self.debug = debug != false
74
+ def load(*)
75
+ super.tap { load_presets }
74
76
  end
75
77
 
76
78
  def log_level
@@ -97,6 +99,8 @@ module AnyCable
97
99
  --redis-channel=name Redis channel for broadcasting, default: "__anycable__"
98
100
  --redis-sentinels=<...hosts> Redis Sentinel followers addresses (as a comma-separated list), default: nil
99
101
  --redis-tls-verify=yes|no Whether to perform server certificate check in case of rediss:// protocol. Default: yes
102
+ --redis-tls-client_cert-path=path Default: nil
103
+ --redis-tls-client_key-path=path Default: nil
100
104
 
101
105
  NATS PUB/SUB
102
106
  --nats-servers=<...addresses> NATS servers for pub/sub, default: "nats://localhost:4222"
@@ -122,9 +126,23 @@ module AnyCable
122
126
 
123
127
  params[:sentinels] = sentinels.map { |sentinel| parse_sentinel(sentinel) }
124
128
  end.tap do |params|
125
- next unless redis_url.match?(/rediss:\/\//) && !redis_tls_verify?
126
-
127
- params[:ssl_params] = {verify_mode: OpenSSL::SSL::VERIFY_NONE}
129
+ next unless redis_url.match?(/rediss:\/\//)
130
+
131
+ if !!redis_tls_client_cert_path ^ !!redis_tls_client_key_path
132
+ raise_validation_error "Both Redis TLS client certificate and private key must be specified (or none of them)"
133
+ end
134
+
135
+ if !redis_tls_verify?
136
+ params[:ssl_params] = {verify_mode: OpenSSL::SSL::VERIFY_NONE}
137
+ else
138
+ cert_path, key_path = redis_tls_client_cert_path, redis_tls_client_key_path
139
+ if cert_path && key_path
140
+ params[:ssl_params] = {
141
+ cert: OpenSSL::X509::Certificate.new(File.read(cert_path)),
142
+ key: OpenSSL::PKey.read(File.read(key_path))
143
+ }
144
+ end
145
+ end
128
146
  end
129
147
  end
130
148
 
@@ -155,5 +173,42 @@ module AnyCable
155
173
  opts[:password] = uri.password if uri.password
156
174
  end
157
175
  end
176
+
177
+ def load_presets
178
+ if presets.nil? || presets.empty?
179
+ self.presets = detect_presets
180
+ __trace__&.record_value(presets, :presets, type: :env)
181
+ end
182
+
183
+ return if presets.empty?
184
+
185
+ presets.each { send(:"load_#{_1}_presets") if respond_to?(:"load_#{_1}_presets", true) }
186
+ end
187
+
188
+ def detect_presets
189
+ [].tap do
190
+ _1 << "fly" if ENV.key?("FLY_APP_NAME") && ENV.key?("FLY_ALLOC_ID") && ENV.key?("FLY_REGION")
191
+ end
192
+ end
193
+
194
+ def load_fly_presets
195
+ write_preset(:rpc_host, "0.0.0.0:50051", preset: "fly")
196
+
197
+ ws_app_name = ENV["ANYCABLE_FLY_WS_APP_NAME"]
198
+ return unless ws_app_name
199
+
200
+ region = ENV.fetch("FLY_REGION")
201
+
202
+ write_preset(:http_broadcast_url, "http://#{region}.#{ws_app_name}.internal:8090/_broadcast", preset: "fly")
203
+ write_preset(:nats_servers, "nats://#{region}.#{ws_app_name}.internal:4222", preset: "fly")
204
+ end
205
+
206
+ def write_preset(key, value, preset:)
207
+ # do not override explicitly provided values
208
+ return unless __trace__&.dig(key.to_s)&.source&.dig(:type) == :defaults
209
+
210
+ write_config_attr(key, value)
211
+ __trace__&.record_value(value, key, type: :preset, preset: preset)
212
+ end
158
213
  end
159
214
  end
@@ -3,13 +3,12 @@
3
3
  AnyCable::Config.attr_config(
4
4
  ### gRPC options
5
5
  rpc_host: "127.0.0.1:50051",
6
- # For defaults see https://github.com/grpc/grpc/blob/51f0d35509bcdaba572d422c4f856208162022de/src/ruby/lib/grpc/generic/rpc_server.rb#L186-L216
7
- rpc_pool_size: ::GRPC::RpcServer::DEFAULT_POOL_SIZE,
8
- rpc_max_waiting_requests: ::GRPC::RpcServer::DEFAULT_MAX_WAITING_REQUESTS,
9
- rpc_poll_period: ::GRPC::RpcServer::DEFAULT_POLL_PERIOD,
10
- rpc_pool_keep_alive: ::GRPC::Pool::DEFAULT_KEEP_ALIVE,
11
- # https://github.com/grpc/grpc/blob/f526602bff029b8db50a8d57134d72da33d8a752/include/grpc/impl/codegen/grpc_types.h#L141-L351
6
+ rpc_pool_size: 30,
7
+ rpc_max_waiting_requests: 20,
8
+ rpc_poll_period: 1,
9
+ rpc_pool_keep_alive: 0.25,
12
10
  rpc_server_args: {},
11
+ rpc_max_connection_age: 300,
13
12
  log_grpc: false
14
13
  )
15
14
 
@@ -33,7 +32,7 @@ module AnyCable
33
32
  max_waiting_requests: rpc_max_waiting_requests,
34
33
  poll_period: rpc_poll_period,
35
34
  pool_keep_alive: rpc_pool_keep_alive,
36
- server_args: normalized_grpc_server_args
35
+ server_args: enhance_grpc_server_args(normalized_grpc_server_args)
37
36
  }
38
37
  end
39
38
 
@@ -46,6 +45,14 @@ module AnyCable
46
45
  skey.start_with?("grpc.") ? skey : "grpc.#{skey}"
47
46
  end
48
47
  end
48
+
49
+ def enhance_grpc_server_args(opts)
50
+ return opts if opts.key?("grpc.max_connection_age_ms")
51
+ return opts unless rpc_max_connection_age.to_i > 0
52
+
53
+ opts["grpc.max_connection_age_ms"] = rpc_max_connection_age.to_i * 1000
54
+ opts
55
+ end
49
56
  end
50
57
  end
51
58
  end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "anycable/grpc/handler"
4
+
5
+ module AnyCable
6
+ module GRPC
7
+ raise LoadError, "AnyCable::GRPC::Server has been already loaded!" if defined?(AnyCable::GRPC::Server)
8
+
9
+ using(Module.new do
10
+ refine ::GrpcKit::Server do
11
+ attr_reader :max_pool_size
12
+
13
+ def stopped?
14
+ @stopping
15
+ end
16
+ end
17
+ end)
18
+
19
+ # Wrapper over gRPC kit server.
20
+ #
21
+ # Basic example:
22
+ #
23
+ # # create new server listening on the loopback interface with 50051 port
24
+ # server = AnyCable::GrpcKit::Server.new(host: "127.0.0.1:50051")
25
+ #
26
+ # # run gRPC server in bakground
27
+ # server.start
28
+ #
29
+ # # stop server
30
+ # server.stop
31
+ class Server
32
+ attr_reader :grpc_server, :host, :hostname, :port, :sock
33
+
34
+ def initialize(host:, logger: nil, **options)
35
+ @logger = logger
36
+ @host = host
37
+
38
+ host_parts = host.match(/\A(?<hostname>.+):(?<port>\d{2,5})\z/)
39
+
40
+ @hostname = host_parts[:hostname]
41
+ @port = host_parts[:port].to_i
42
+
43
+ @grpc_server = build_server(**options)
44
+ end
45
+
46
+ # Start gRPC server in background and
47
+ # wait untill it ready to accept connections
48
+ def start
49
+ return if running?
50
+
51
+ raise "Cannot re-start stopped server" if stopped?
52
+
53
+ logger.info "RPC server (grpc_kit) is starting..."
54
+
55
+ @sock = TCPServer.new(hostname, port)
56
+
57
+ server = grpc_server
58
+
59
+ @start_thread = Thread.new do
60
+ loop do
61
+ conn = @sock.accept
62
+ server.run(conn)
63
+ rescue IOError
64
+ # ignore broken connections
65
+ end
66
+ end
67
+
68
+ wait_till_running
69
+
70
+ logger.info "RPC server is listening on #{host} (workers_num: #{grpc_server.max_pool_size})"
71
+ end
72
+
73
+ def wait_till_running
74
+ raise "Server is not running" unless running?
75
+
76
+ timeout = 5
77
+
78
+ loop do
79
+ sock = TCPSocket.new(hostname, port, connect_timeout: 1)
80
+ stub = AnyCable::GRPC::Stub.new(sock)
81
+ stub.connect(AnyCable::ConnectionRequest.new(env: {}))
82
+ sock.close
83
+ break
84
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError
85
+ timeout -= 1
86
+ raise "Server is not responding" if timeout.zero?
87
+ end
88
+ end
89
+
90
+ def wait_till_terminated
91
+ raise "Server is not running" unless running?
92
+
93
+ start_thread.join
94
+ end
95
+
96
+ # Stop gRPC server if it's running
97
+ def stop
98
+ return unless running?
99
+
100
+ return if stopped?
101
+
102
+ grpc_server.graceful_shutdown
103
+ sock.close
104
+
105
+ logger.info "RPC server stopped"
106
+ end
107
+
108
+ def running?
109
+ !!sock
110
+ end
111
+
112
+ def stopped?
113
+ grpc_server.stopped?
114
+ end
115
+
116
+ private
117
+
118
+ attr_reader :start_thread
119
+
120
+ def logger
121
+ @logger ||= AnyCable.logger
122
+ end
123
+
124
+ def build_server(**options)
125
+ pool_size = options[:pool_size]
126
+
127
+ ::GrpcKit::Server.new(min_pool_size: pool_size, max_pool_size: pool_size).tap do |server|
128
+ server.handle(AnyCable::GRPC::Handler)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "grpc_kit"
4
+
5
+ module AnyCable
6
+ module GRPC
7
+ end
8
+ end
9
+
10
+ require "anycable/grpc/config"
11
+ require "anycable/grpc_kit/server"
12
+
13
+ AnyCable.server_builder = ->(config) {
14
+ AnyCable.logger.info "gRPC Kit version: #{::GrpcKit::VERSION}"
15
+
16
+ ::GrpcKit.loglevel = :fatal
17
+ ::GrpcKit.logger = AnyCable.logger if config.log_grpc?
18
+
19
+ params = config.to_grpc_params
20
+
21
+ AnyCable::GRPC::Server.new(**params, host: config.rpc_host)
22
+ }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnyCable
4
- VERSION = "1.2.5"
4
+ VERSION = "1.3.0"
5
5
  end
data/lib/anycable.rb CHANGED
@@ -109,11 +109,23 @@ module AnyCable
109
109
  end
110
110
  end
111
111
 
112
- # gRPC is the default for now, so, let's try to load it.
113
- begin
114
- require "anycable/grpc"
115
- rescue LoadError => e
116
- # Re-raise an exception if we failed to load grpc .so files
117
- # (e.g., on Alpine Linux)
118
- raise if /(error loading shared library|incompatible architecture)/i.match?(e.message)
112
+ # Try loading a gRPC implementation
113
+ impl = ENV.fetch("ANYCABLE_GRPC_IMPL", "grpc")
114
+
115
+ case impl
116
+ when "grpc"
117
+ begin
118
+ require "grpc/version"
119
+ require "anycable/grpc"
120
+ rescue LoadError => e
121
+ # Re-raise an exception if we failed to load grpc .so files
122
+ # (e.g., on Alpine Linux)
123
+ raise if /(error loading shared library|incompatible architecture)/i.match?(e.message)
124
+ end
125
+ when "grpc_kit"
126
+ begin
127
+ require "grpc_kit/version"
128
+ require "anycable/grpc_kit"
129
+ rescue LoadError
130
+ end
119
131
  end
@@ -1,5 +1,7 @@
1
1
  module AnyCable
2
2
  interface _Config
3
+ def presets: () -> Array[String]
4
+ def presets=: (Array[String]) -> void
3
5
  def broadcast_adapter: () -> Symbol
4
6
  def broadcast_adapter=: (Symbol) -> void
5
7
  def redis_url: () -> String
@@ -9,14 +11,19 @@ module AnyCable
9
11
  def redis_channel: () -> String
10
12
  def redis_channel=: (String) -> void
11
13
  def redis_tls_verify: () -> bool
12
- def redis_tls_verify?: () -> bool
13
14
  def redis_tls_verify=: (bool) -> void
15
+ def redis_tls_verify?: () -> bool
16
+ def redis_tls_client_cert_path: () -> String?
17
+ def redis_tls_client_cert_path=: (String) -> void
18
+ def redis_tls_client_key_path: () -> String?
19
+ def redis_tls_client_key_path=: (String) -> void
14
20
  def nats_servers: () -> Array[String]
15
21
  def nats_servers=: (Array[String]) -> void
16
22
  def nats_channel: () -> String
17
23
  def nats_channel=: (String) -> void
18
24
  def nats_dont_randomize_servers: () -> bool
19
25
  def nats_dont_randomize_servers=: (bool) -> void
26
+ def nats_dont_randomize_servers?: () -> bool
20
27
  def nats_options: () -> Hash[untyped, untyped]
21
28
  def nats_options=: (Hash[untyped, untyped]) -> void
22
29
  def http_broadcast_url: () -> String
@@ -29,12 +36,17 @@ module AnyCable
29
36
  def log_level=: (String) -> void
30
37
  def debug: () -> bool
31
38
  def debug=: (bool) -> void
39
+ def debug?: () -> bool
32
40
  def http_health_port: () -> Integer?
33
41
  def http_health_port=: (Integer) -> void
34
42
  def http_health_path: () -> String
35
43
  def http_health_path=: (String) -> void
36
44
  def version_check_enabled: () -> bool
37
45
  def version_check_enabled=: (bool) -> void
46
+ def version_check_enabled?: () -> bool
47
+ def sid_header_enabled: () -> bool
48
+ def sid_header_enabled=: (bool) -> void
49
+ def sid_header_enabled?: () -> bool
38
50
  end
39
51
 
40
52
  class Config < Anyway::Config
@@ -46,6 +58,7 @@ module AnyCable
46
58
  alias debug? debug
47
59
  alias version_check_enabled? version_check_enabled
48
60
 
61
+ def load: (*untyped) -> void
49
62
  def http_health_port_provided?: () -> bool
50
63
  def to_redis_params: () -> { url: String, sentinels: Array[untyped]?, ssl_params: Hash[Symbol, untyped]? }
51
64
  def to_http_health_params: () -> { port: Integer?, path: String }
@@ -54,5 +67,10 @@ module AnyCable
54
67
  private
55
68
 
56
69
  def parse_sentinel: ((String | Hash[untyped, untyped]) sentinel) -> Hash[Symbol, untyped]
70
+ def load_presets: () -> void
71
+ def detect_presets: () -> Array[String]
72
+ def write_preset: (Symbol, untyped, preset: String) -> void
73
+ def write_config_attr: (Symbol, untyped) -> void
74
+ def __trace__: () -> untyped
57
75
  end
58
76
  end
@@ -7,30 +7,38 @@ module AnyCable
7
7
  def rpc_pool_size=: (Integer) -> void
8
8
  def rpc_max_waiting_requests: () -> Integer
9
9
  def rpc_max_waiting_requests=: (Integer) -> void
10
- def rpc_poll_period: () -> Integer
11
- def rpc_poll_period=: (Integer) -> void
12
- def rpc_pool_keep_alive: () -> Integer
13
- def rpc_pool_keep_alive=: (Integer) -> void
10
+ def rpc_poll_period: () -> Numeric
11
+ def rpc_poll_period=: (Numeric) -> void
12
+ def rpc_pool_keep_alive: () -> Numeric
13
+ def rpc_pool_keep_alive=: (Numeric) -> void
14
+ def rpc_max_connection_age: () -> Integer
15
+ def rpc_max_connection_age=: (Integer) -> void
14
16
  def rpc_server_args: () -> Hash[Symbol | String, untyped]?
15
17
  def rpc_server_args=: (Hash[Symbol | String, untyped]) -> void
16
18
  def log_grpc: () -> bool
17
19
  def log_grpc=: (bool) -> void
20
+ def log_grpc?: () -> bool
18
21
  end
19
22
 
20
- module Config : AnyCable::Config
23
+ module Config : AnyCable::_Config
21
24
  include _Config
22
25
 
23
- alias log_grpc? log_grpc
24
-
25
26
  def to_grpc_params: () -> {
26
27
  pool_size: Integer,
27
28
  max_waiting_requests: Integer,
28
- poll_period: Integer,
29
- pool_keep_alive: Integer,
29
+ poll_period: Numeric,
30
+ pool_keep_alive: Numeric,
30
31
  server_args: Hash[String, untyped]
31
32
  }
32
33
 
33
34
  def normalized_grpc_server_args: () -> Hash[String, untyped]
35
+ def enhance_grpc_server_args: (Hash[String, untyped]) -> Hash[String, untyped]
34
36
  end
35
37
  end
36
38
  end
39
+
40
+ module AnyCable
41
+ class Config
42
+ include GRPC::Config
43
+ end
44
+ end
@@ -6,7 +6,7 @@ module AnyCable
6
6
  attr_reader grpc_server: untyped
7
7
  attr_reader host: String
8
8
 
9
- def initialize: (host: String, ?logger: Logger, **untyped options) -> void
9
+ def initialize: (host: String, ?logger: Logger?, **untyped options) -> void
10
10
 
11
11
  private
12
12
 
@@ -12,7 +12,7 @@ module AnyCable
12
12
  attr_reader path: String
13
13
  attr_reader http_server: untyped
14
14
 
15
- def initialize: (_Runnable server, port: Integer port, ?logger: Logger logger, ?path: String path) -> void
15
+ def initialize: (_Runnable server, port: Integer port, ?logger: Logger? logger, ?path: String path) -> void
16
16
  def start: () -> void
17
17
  def stop: () -> void
18
18
  def running?: () -> bool
@@ -1,5 +1,5 @@
1
1
  module AnyCable
2
2
  class Middleware
3
- def call: (Symbol, rpcRequest, rpcMetadata) { (Symbol, rpcRequest, rpcMetadata) -> rpcResponse } -> rpcResponse
3
+ def call: (Symbol, rpcRequest, rpcMetadata) { () -> rpcResponse } -> rpcResponse
4
4
  end
5
5
  end
data/sig/anycable/rpc.rbs CHANGED
@@ -12,6 +12,12 @@ module AnyCable
12
12
  type protoMap = _ProtobufMap
13
13
  type rpcMetadata = Hash[String, String]
14
14
 
15
+ module Status
16
+ SUCCESS: 0
17
+ FAILURE: 1
18
+ ERROR: 2
19
+ end
20
+
15
21
  interface _WithEnvState
16
22
  def cstate: () -> protoMap?
17
23
  def cstate=: (protoMap) -> void
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anycable-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2023-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.1.0
19
+ version: '2.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.1.0
26
+ version: '2.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: google-protobuf
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,34 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '3.5'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov-lcov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: webmock
127
155
  requirement: !ruby/object:Gem::Requirement
@@ -181,6 +209,8 @@ files:
181
209
  - lib/anycable/grpc/handler.rb
182
210
  - lib/anycable/grpc/rpc_services_pb.rb
183
211
  - lib/anycable/grpc/server.rb
212
+ - lib/anycable/grpc_kit.rb
213
+ - lib/anycable/grpc_kit/server.rb
184
214
  - lib/anycable/health_server.rb
185
215
  - lib/anycable/middleware.rb
186
216
  - lib/anycable/middleware_chain.rb
@@ -241,14 +271,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
241
271
  requirements:
242
272
  - - ">="
243
273
  - !ruby/object:Gem::Version
244
- version: 2.6.0
274
+ version: 2.7.0
245
275
  required_rubygems_version: !ruby/object:Gem::Requirement
246
276
  requirements:
247
277
  - - ">="
248
278
  - !ruby/object:Gem::Version
249
279
  version: '0'
250
280
  requirements: []
251
- rubygems_version: 3.3.11
281
+ rubygems_version: 3.4.6
252
282
  signing_key:
253
283
  specification_version: 4
254
284
  summary: AnyCable core RPC implementation