anycable-core 1.2.5 → 1.3.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/CHANGELOG.md +21 -2
- data/MIT-LICENSE +1 -1
- data/README.md +3 -2
- data/lib/anycable/broadcast_adapters/redis.rb +1 -1
- data/lib/anycable/broadcast_adapters.rb +1 -1
- data/lib/anycable/cli.rb +1 -1
- data/lib/anycable/config.rb +71 -16
- data/lib/anycable/grpc/config.rb +14 -7
- data/lib/anycable/grpc_kit/server.rb +133 -0
- data/lib/anycable/grpc_kit.rb +22 -0
- data/lib/anycable/version.rb +1 -1
- data/lib/anycable.rb +19 -7
- data/sig/anycable/config.rbs +19 -1
- data/sig/anycable/grpc/config.rbs +17 -9
- data/sig/anycable/grpc/server.rbs +1 -1
- data/sig/anycable/health_server.rbs +1 -1
- data/sig/anycable/middleware.rbs +1 -1
- data/sig/anycable/rpc.rbs +6 -0
- metadata +38 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 215d37d67fe10f536e6eb2a9b8ae5e53603d4653fb2034aff9abece234da7097
|
|
4
|
+
data.tar.gz: 50457dfd126925e875f3bb1ab323df90a0381f13de399f07e20a8cd4f2cab5d7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
data/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
[](https://rubygems.org/gems/anycable)
|
|
2
2
|
[](https://github.com/anycable/anycable/actions)
|
|
3
|
+
[](https://coveralls.io/github/anycable/anycable?branch=master)
|
|
3
4
|
[](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.
|
|
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
|
|
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:
|
|
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
|
data/lib/anycable/config.rb
CHANGED
|
@@ -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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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:\/\//)
|
|
126
|
-
|
|
127
|
-
|
|
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
|
data/lib/anycable/grpc/config.rb
CHANGED
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
AnyCable::Config.attr_config(
|
|
4
4
|
### gRPC options
|
|
5
5
|
rpc_host: "127.0.0.1:50051",
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
+
}
|
data/lib/anycable/version.rb
CHANGED
data/lib/anycable.rb
CHANGED
|
@@ -109,11 +109,23 @@ module AnyCable
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
#
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
data/sig/anycable/config.rbs
CHANGED
|
@@ -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: () ->
|
|
11
|
-
def rpc_poll_period=: (
|
|
12
|
-
def rpc_pool_keep_alive: () ->
|
|
13
|
-
def rpc_pool_keep_alive=: (
|
|
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::
|
|
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:
|
|
29
|
-
pool_keep_alive:
|
|
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
|
|
@@ -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
|
data/sig/anycable/middleware.rbs
CHANGED
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.
|
|
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:
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
281
|
+
rubygems_version: 3.4.6
|
|
252
282
|
signing_key:
|
|
253
283
|
specification_version: 4
|
|
254
284
|
summary: AnyCable core RPC implementation
|