anycable-core 1.2.0 → 1.2.1

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: b4c85f8eab809e414507ed9e35da7381b9ca2626ad4c9e2e4f84a5ee8dda2d09
4
- data.tar.gz: 37edd04f4c524384c989a774f94e7a8ede624f7fe95e3a6f1a864f2c11f03b4e
3
+ metadata.gz: 5f387a5b5a0a7535f698339c719f4f7f8debd3c799f5e69b7b54b46b599d3830
4
+ data.tar.gz: 558f452d571cd33557836861083539fa130c266d5ded16764f0137a9494c39d2
5
5
  SHA512:
6
- metadata.gz: 15602cd4712a4a451e41c03035b176d0fc276593852ab93f386e588d297f7a3e7be8284e8feb952fb19b8a0918973edb48c6a9ce2bd0fb8a63a0ceb068c12730
7
- data.tar.gz: a8453ffddde915bd88e2c5fd8cad6178194c8ca7ad3193f617157c6a92b5504022d4a11572e7bb61cc9157897857ab00b7dbab609961ee9ad7d9b55321f66ea9
6
+ metadata.gz: 819b9da9e51dae8e6feca6be71550c72e3aaee4358e8245c95235a030f9ee130d3b49d48590eb3d4abc8275a7918c71130b48fd63e3b4b9a5fd46d34520942c7
7
+ data.tar.gz: c3409d81a2b9c66593384de64d0cc66ac1c31d915d58a836af1c222438d152f18ca86830a86c7867b784ba2159aa80787a5abd5ea3b50d8edd99b835d572bbe8
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.2.1 (2022-02-21)
6
+
7
+ - Fix RBS signature. ([@palkan][])
8
+
9
+ - Add empty (`''`) service to gRPC health check as "NOT_SERVING". ([@palkan][])
10
+
5
11
  ## 1.2.0 (2021-12-21) 🎄
6
12
 
7
13
  - Drop Ruby 2.6 support.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2017-2021 Vladimir Dementyev
1
+ Copyright 2017-2022 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,6 +1,5 @@
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
- [![Gitter](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/anycable/Lobby)
4
3
  [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io/v1)
5
4
 
6
5
  # AnyCable
@@ -30,7 +30,7 @@ module AnyCable
30
30
  **options
31
31
  )
32
32
  options = AnyCable.config.to_redis_params.merge(options)
33
- @redis_conn = ::Redis.new(options)
33
+ @redis_conn = ::Redis.new(**options)
34
34
  @channel = channel
35
35
  end
36
36
 
data/lib/anycable/cli.rb CHANGED
@@ -119,7 +119,7 @@ module AnyCable
119
119
  def wait_till_terminated
120
120
  self_read = setup_signals
121
121
 
122
- while readable_io = IO.select([self_read]) # rubocop:disable Lint/AssignmentInCondition
122
+ while readable_io = IO.select([self_read]) # rubocop:disable Lint/AssignmentInCondition,Lint/IncompatibleIoSelectWithFiberScheduler
123
123
  signal = readable_io.first[0].gets.strip
124
124
  raise Interrupt, "SIG#{signal} received"
125
125
  end
@@ -74,7 +74,7 @@ module AnyCable
74
74
 
75
75
  HTTP HEALTH CHECKER
76
76
  --http-health-port=port Port to run HTTP health server on, default: <none> (disabled)
77
- --http-health-path=path Endpoint to server health cheks, default: "/health"
77
+ --http-health-path=path Endpoint to serve health checks, default: "/health"
78
78
 
79
79
  REDIS PUB/SUB
80
80
  --redis-url=url Redis URL for pub/sub, default: REDIS_URL or "redis://localhost:6379/5"
@@ -96,6 +96,10 @@ module AnyCable
96
96
  "anycable.RPC",
97
97
  Grpc::Health::V1::HealthCheckResponse::ServingStatus::SERVING
98
98
  )
99
+ health_checker.add_status(
100
+ "",
101
+ Grpc::Health::V1::HealthCheckResponse::ServingStatus::NOT_SERVING
102
+ )
99
103
  health_checker
100
104
  end
101
105
  end
@@ -65,7 +65,15 @@ module AnyCable
65
65
  AccessLog: []
66
66
  ).tap do |http_server|
67
67
  http_server.mount_proc path do |_, res|
68
- res.status, res.body = server.running? ? SUCCESS_RESPONSE : FAILURE_RESPONSE
68
+ # Replace with mass assignment as soon as Steep added support
69
+ # https://github.com/soutaro/steep/issues/424
70
+ if server.running?
71
+ res.status = SUCCESS_RESPONSE.first
72
+ res.body = SUCCESS_RESPONSE.last
73
+ else
74
+ res.status = FAILURE_RESPONSE.first
75
+ res.body = FAILURE_RESPONSE.last
76
+ end
69
77
  end
70
78
  end
71
79
  end
@@ -116,22 +116,23 @@ module AnyCable
116
116
  # Build Rack env from request
117
117
  def build_rack_env
118
118
  uri = URI.parse(request_env.url)
119
+ headers = request_env.headers.to_h
119
120
 
120
121
  env = base_rack_env
121
122
  env.merge!({
122
123
  "PATH_INFO" => uri.path,
123
124
  "QUERY_STRING" => uri.query,
124
125
  "SERVER_NAME" => uri.host,
125
- "SERVER_PORT" => uri.port,
126
+ "SERVER_PORT" => uri.port&.to_s,
126
127
  "HTTP_HOST" => uri.host,
127
- "REMOTE_ADDR" => request_env.headers.delete("REMOTE_ADDR"),
128
+ "REMOTE_ADDR" => headers.delete("REMOTE_ADDR"),
128
129
  "rack.url_scheme" => uri.scheme&.sub(/^ws/, "http"),
129
130
  # AnyCable specific fields
130
131
  "anycable.raw_cstate" => request_env.cstate&.to_h,
131
132
  "anycable.raw_istate" => request_env.istate&.to_h
132
133
  }.delete_if { |_k, v| v.nil? })
133
134
 
134
- env.merge!(build_headers(request_env.headers))
135
+ env.merge!(build_headers(headers))
135
136
  end
136
137
 
137
138
  def base_rack_env
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnyCable
4
- VERSION = "1.2.0"
4
+ VERSION = "1.2.1"
5
5
  end
data/lib/anycable.rb CHANGED
@@ -114,5 +114,5 @@ begin
114
114
  rescue LoadError => e
115
115
  # Re-raise an exception if we failed to load grpc .so files
116
116
  # (e.g., on Alpine Linux)
117
- raise if /Error loading shared library/.match?(e.message)
117
+ raise if /(error loading shared library|incompatible architecture)/i.match?(e.message)
118
118
  end
@@ -0,0 +1,18 @@
1
+ module AnyCable
2
+ interface _BroadcastAdapter
3
+ def raw_broadcast: (String _data) -> void
4
+ def broadcast: (String stream, String payload) -> void
5
+ def broadcast_command: (String command, **untyped payload) -> void
6
+ def announce!: () -> void
7
+ end
8
+
9
+ module BroadcastAdapters
10
+ class Base
11
+ include _BroadcastAdapter
12
+
13
+ private
14
+
15
+ def logger: () -> Logger
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module AnyCable
2
+ module BroadcastAdapters
3
+ class Http < Base
4
+ RECOVERABLE_EXCEPTIONS: Array[singleton(Class)]
5
+ OPEN_TIMEOUT: Integer
6
+ READ_TIMEOUT: Integer
7
+ MAX_ATTEMPTS: Integer
8
+ DELAY: Integer
9
+
10
+ attr_reader url: String
11
+ attr_reader headers: Hash[String, String]
12
+ attr_reader authorized: bool
13
+
14
+ alias authorized? authorized
15
+
16
+ def initialize: (?url: String url, ?secret: String secret) -> void
17
+ def shutdown: () -> void
18
+
19
+ private
20
+
21
+ attr_reader uri: URI::Generic
22
+ attr_reader queue: Thread::Queue
23
+ attr_reader thread: Thread?
24
+
25
+ def ensure_thread_is_alive: () -> void
26
+ def perform_request: (String payload) -> untyped
27
+ def handle_response: (untyped response) -> void
28
+ def build_http: () { (untyped) -> untyped } -> untyped
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,10 @@
1
+ module AnyCable
2
+ module BroadcastAdapters
3
+ class Redis < Base
4
+ attr_reader redis_conn: untyped
5
+ attr_reader channel: String
6
+
7
+ def initialize: (?channel: String channel, **untyped options) -> void
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,36 @@
1
+ module AnyCable
2
+ module GRPC
3
+ interface _Config
4
+ def rpc_host: () -> String
5
+ def rpc_host=: (String) -> void
6
+ def rpc_pool_size: () -> Integer
7
+ def rpc_pool_size=: (Integer) -> void
8
+ def rpc_max_waiting_requests: () -> Integer
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
14
+ def rpc_server_args: () -> Hash[Symbol | String, untyped]?
15
+ def rpc_server_args=: (Hash[Symbol | String, untyped]) -> void
16
+ def log_grpc: () -> bool
17
+ def log_grpc=: (bool) -> void
18
+ end
19
+
20
+ module Config : AnyCable::Config
21
+ include _Config
22
+
23
+ alias log_grpc? log_grpc
24
+
25
+ def to_grpc_params: () -> {
26
+ pool_size: Integer,
27
+ max_waiting_requests: Integer,
28
+ poll_period: Integer,
29
+ pool_keep_alive: Integer,
30
+ server_args: Hash[String, untyped]
31
+ }
32
+
33
+ def normalized_grpc_server_args: () -> Hash[String, untyped]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ module AnyCable
2
+ module GRPC
3
+ # RPC service handler
4
+ class Handler < AnyCable::GRPC::Service
5
+ # Handle connection request from WebSocket server
6
+ def connect: (untyped request, untyped _unused_call) -> untyped
7
+ def disconnect: (untyped request, untyped _unused_call) -> untyped
8
+ def command: (untyped request, untyped _unused_call) -> untyped
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module AnyCable
2
+ module GRPC
3
+ class Service
4
+ end
5
+
6
+ Stub: untyped
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ module AnyCable
2
+ module GRPC
3
+ class Server
4
+ include _Server
5
+
6
+ attr_reader grpc_server: untyped
7
+ attr_reader host: String
8
+
9
+ def initialize: (host: String, ?logger: Logger, **untyped options) -> void
10
+
11
+ private
12
+
13
+ attr_reader start_thread: Thread
14
+
15
+ def logger: () -> Logger
16
+ def build_server: (**untyped options) -> untyped
17
+ def build_health_checker: () -> untyped
18
+ end
19
+ end
20
+ end
@@ -1,14 +1,18 @@
1
1
  module AnyCable
2
2
  class HealthServer
3
+ interface _Runnable
4
+ def running?: () -> bool
5
+ end
6
+
3
7
  SUCCESS_RESPONSE: Array[Integer | String]
4
8
  FAILURE_RESPONSE: Array[Integer | String]
5
9
 
6
- attr_reader server: _Server
10
+ attr_reader server: _Runnable
7
11
  attr_reader port: Integer
8
12
  attr_reader path: String
9
13
  attr_reader http_server: untyped
10
14
 
11
- def initialize: (_Server 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
12
16
  def start: () -> void
13
17
  def stop: () -> void
14
18
  def running?: () -> bool
@@ -0,0 +1,10 @@
1
+ module AnyCable
2
+ module Middlewares
3
+ class CheckVersion < AnyCable::Middleware
4
+ attr_reader version: String
5
+
6
+ def initialize: (String version) -> void
7
+ def check_version: (rpcMetadata) { () -> untyped } -> untyped
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module AnyCable
2
+ module Middlewares
3
+ class Exceptions < AnyCable::Middleware
4
+ private
5
+
6
+ def notify_exception: (StandardError exp, Symbol method_name, rpcRequest request) -> void
7
+ def response_class: (Symbol method_name) -> untyped
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ module AnyCable
2
+ module RPC
3
+ interface _Handler
4
+ def build_socket: (env: Env) -> Socket
5
+ def build_env_response: (Socket socket) -> EnvResponse
6
+ def logger: () -> Logger
7
+ def factory: () -> _ConnectionFactory
8
+ end
9
+
10
+ class Handler
11
+ include _Handler
12
+ include Handlers::Connect
13
+ include Handlers::Disconnect
14
+ include Handlers::Command
15
+
16
+ def initialize: (?middleware: MiddlewareChain) -> void
17
+ def handle: (Symbol cmd, rpcRequest data, ?rpcMetadata meta) -> rpcResponse
18
+
19
+ private
20
+
21
+ attr_reader middleware: MiddlewareChain
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module AnyCable
2
+ module RPC
3
+ module Handlers
4
+ module Command : _Handler
5
+ def command: (CommandMessage message) -> CommandResponse
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module AnyCable
2
+ module RPC
3
+ module Handlers
4
+ module Connect : _Handler
5
+ def connect: (ConnectionRequest request) -> ConnectionResponse
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module AnyCable
2
+ module RPC
3
+ module Handlers
4
+ module Disconnect : _Handler
5
+ def disconnect: (DisconnectRequest request) -> DisconnectResponse
6
+ end
7
+ end
8
+ end
9
+ end
data/sig/anycable/rpc.rbs CHANGED
@@ -2,8 +2,14 @@ module AnyCable
2
2
  PROTO_VERSION: ::String
3
3
  SESSION_KEY: ::String
4
4
 
5
+ interface _ProtobufMap
6
+ def []: (String key) -> String
7
+ def []=: (String key, String val) -> String
8
+ def to_h: () -> Hash[String, String]
9
+ end
10
+
5
11
  type rpcStatus = 0 | 1 | 2
6
- type protoMap = Hash[String, String]
12
+ type protoMap = _ProtobufMap
7
13
  type rpcMetadata = Hash[String, String]
8
14
 
9
15
  interface _WithEnvState
@@ -38,7 +44,7 @@ module AnyCable
38
44
  end
39
45
 
40
46
  module WithConnectionState : _WithEnv, _ProtoMessage
41
- def initialize: (?session: untyped? session, **untyped other) -> untyped
47
+ %a{rbs:test:skip} def initialize: (?session: untyped? session, **untyped other) -> untyped
42
48
 
43
49
  def session=: (untyped val) -> untyped
44
50
  def session: () -> untyped
@@ -60,8 +66,8 @@ module AnyCable
60
66
  class ConnectionRequest
61
67
  include _WithEnv
62
68
 
63
- def initialize: (?env: Env) -> void
64
- def to_h: () -> Hash[String, untyped]
69
+ %a{rbs:test:skip} def initialize: (?env: Env) -> void
70
+ def to_h: () -> Hash[Symbol, untyped]
65
71
  end
66
72
 
67
73
  class ConnectionResponse
@@ -73,7 +79,7 @@ module AnyCable
73
79
  attr_accessor error_msg: String?
74
80
  attr_accessor env: EnvResponse
75
81
 
76
- def initialize: (
82
+ %a{rbs:test:skip} def initialize: (
77
83
  status: rpcStatus,
78
84
  ?identifiers: String,
79
85
  ?transmissions: Array[String],
@@ -81,7 +87,7 @@ module AnyCable
81
87
  ?env: EnvResponse
82
88
  ) -> void
83
89
 
84
- def to_h: () -> Hash[String, untyped]
90
+ def to_h: () -> Hash[Symbol, untyped]
85
91
  end
86
92
 
87
93
  class CommandMessage
@@ -92,14 +98,14 @@ module AnyCable
92
98
  attr_accessor connection_identifiers: String
93
99
  attr_accessor data: String
94
100
 
95
- def initialize: (
101
+ %a{rbs:test:skip} def initialize: (
96
102
  command: String,
97
103
  identifier: String,
98
104
  ?connection_identifiers: String,
99
105
  ?env: Env
100
106
  ) -> void
101
107
 
102
- def to_h: () -> Hash[String, untyped]
108
+ def to_h: () -> Hash[Symbol, untyped]
103
109
  end
104
110
 
105
111
  class CommandResponse
@@ -114,7 +120,7 @@ module AnyCable
114
120
  attr_accessor env: EnvResponse
115
121
  attr_accessor stopped_streams: Array[String]
116
122
 
117
- def initialize: (
123
+ %a{rbs:test:skip} def initialize: (
118
124
  status: rpcStatus,
119
125
  ?disconnect: bool,
120
126
  ?stop_streams: bool,
@@ -125,7 +131,7 @@ module AnyCable
125
131
  ?env: EnvResponse
126
132
  ) -> void
127
133
 
128
- def to_h: () -> Hash[String, untyped]
134
+ def to_h: () -> Hash[Symbol, untyped]
129
135
  end
130
136
 
131
137
  class DisconnectRequest
@@ -134,8 +140,8 @@ module AnyCable
134
140
  attr_accessor identifiers: String
135
141
  attr_accessor subscriptions: Array[String]
136
142
 
137
- def initialize: (identifiers: String, ?subscriptions: Array[String], ?env: Env) -> void
138
- def to_h: () -> Hash[String, untyped]
143
+ %a{rbs:test:skip} def initialize: (identifiers: String, ?subscriptions: Array[String], ?env: Env) -> void
144
+ def to_h: () -> Hash[Symbol, untyped]
139
145
  end
140
146
 
141
147
  class DisconnectResponse
@@ -144,8 +150,8 @@ module AnyCable
144
150
  attr_accessor status: rpcStatus
145
151
  attr_accessor error_msg: String?
146
152
 
147
- def initialize: (status: rpcStatus, ?error_msg: String) -> void
148
- def to_h: () -> Hash[String, untyped]
153
+ %a{rbs:test:skip} def initialize: (status: rpcStatus, ?error_msg: String) -> void
154
+ def to_h: () -> Hash[Symbol, untyped]
149
155
  end
150
156
 
151
157
  type rpcRequest = ConnectionRequest | DisconnectRequest | CommandMessage
@@ -2,12 +2,12 @@ module AnyCable
2
2
  class Socket
3
3
  class State
4
4
  attr_reader dirty_keys: Array[String]?
5
- attr_reader source: protoMap
5
+ attr_reader source: Hash[String, String]
6
6
 
7
- def initialize: (protoMap) -> void
7
+ def initialize: (Hash[String, String]) -> void
8
8
  def read: (String key) -> untyped
9
9
  def write: (String key, String val) -> void
10
- def changed_fields: () -> protoMap?
10
+ def changed_fields: () -> Hash[String, String]?
11
11
 
12
12
  alias [] read
13
13
  alias []= write
data/sig/anycable.rbs CHANGED
@@ -18,7 +18,11 @@ module AnyCable
18
18
 
19
19
  type serverBuilder = ^(Config) -> _Server
20
20
 
21
- attr_accessor self.connection_factory: ^(Socket, ?identifiers: String, ?subscriptions: Array[String]) -> _Connection
21
+ interface _ConnectionFactory
22
+ def call: (Socket, ?identifiers: String, ?subscriptions: Array[String]) -> _Connection
23
+ end
24
+
25
+ attr_accessor self.connection_factory: _ConnectionFactory
22
26
  attr_accessor self.server_builder: serverBuilder
23
27
  attr_writer self.logger: Logger
24
28
  attr_writer self.rpc_handler: RPC::Handler
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.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-21 00:00:00.000000000 Z
11
+ date: 2022-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: steep
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'
153
139
  description: AnyCable core RPC implementation not depenending on a particular server
154
140
  type (e.g., gRPC or whatever)
155
141
  email:
@@ -197,13 +183,26 @@ files:
197
183
  - lib/anycable/version.rb
198
184
  - sig/anycable.rbs
199
185
  - sig/anycable/broadcast_adapters.rbs
186
+ - sig/anycable/broadcast_adapters/base.rbs
187
+ - sig/anycable/broadcast_adapters/http.rbs
188
+ - sig/anycable/broadcast_adapters/redis.rbs
200
189
  - sig/anycable/cli.rbs
201
190
  - sig/anycable/config.rbs
202
191
  - sig/anycable/exceptions_handling.rbs
192
+ - sig/anycable/grpc/config.rbs
193
+ - sig/anycable/grpc/handler.rbs
194
+ - sig/anycable/grpc/rpc_services_pb.rbs
195
+ - sig/anycable/grpc/server.rbs
203
196
  - sig/anycable/health_server.rbs
204
197
  - sig/anycable/middleware.rbs
205
198
  - sig/anycable/middleware_chain.rbs
199
+ - sig/anycable/middlewares/check_version.rbs
200
+ - sig/anycable/middlewares/exceptions.rbs
206
201
  - sig/anycable/rpc.rbs
202
+ - sig/anycable/rpc/handler.rbs
203
+ - sig/anycable/rpc/handlers/command.rbs
204
+ - sig/anycable/rpc/handlers/connect.rbs
205
+ - sig/anycable/rpc/handlers/disconnect.rbs
207
206
  - sig/anycable/socket.rbs
208
207
  - sig/anycable/version.rbs
209
208
  homepage: http://github.com/anycable/anycable