anycable-core 1.2.1 → 1.2.4

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: 5f387a5b5a0a7535f698339c719f4f7f8debd3c799f5e69b7b54b46b599d3830
4
- data.tar.gz: 558f452d571cd33557836861083539fa130c266d5ded16764f0137a9494c39d2
3
+ metadata.gz: 43353c30169b14234846a634a2f6e2cf9b8c205725752fcc9de78ed088e2432a
4
+ data.tar.gz: aa0b65f611dd8598b230d152f4b51ddfbdbd92c020081d957ab3f18179c6623f
5
5
  SHA512:
6
- metadata.gz: 819b9da9e51dae8e6feca6be71550c72e3aaee4358e8245c95235a030f9ee130d3b49d48590eb3d4abc8275a7918c71130b48fd63e3b4b9a5fd46d34520942c7
7
- data.tar.gz: c3409d81a2b9c66593384de64d0cc66ac1c31d915d58a836af1c222438d152f18ca86830a86c7867b784ba2159aa80787a5abd5ea3b50d8edd99b835d572bbe8
6
+ metadata.gz: 6fc3a9531075ec9da6ba4c7dc0e2e00f863829930f80a8b794e40aad13215db134c6195619d272188032502c6ae123f3567d781168580e1eb718d200042910b3
7
+ data.tar.gz: b7d91672f1976952a40315d92956f0d5970947e89d85e6e94a31240e3428e63c56093c173236ef46f25f5da47d5030cfd5576cdce8c248600a9959ceaa5e8145
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.2.4 (2022-08-10)
6
+
7
+ - Add NATS pub/sub adapter. ([@palkan][])
8
+
9
+ - Setting the redis adapter to use the ruby driver. ([@smasry][])
10
+
11
+ ## 1.2.3 (2022-04-20)
12
+
13
+ - Pass unique connection id (_session id_) in the `anycable.sid` Rack env field. ([@palkan][])
14
+
15
+ ## 1.2.2 (2022-03-04)
16
+
17
+ - Allow Ruby 2.6.
18
+
5
19
  ## 1.2.1 (2022-02-21)
6
20
 
7
21
  - Fix RBS signature. ([@palkan][])
@@ -116,3 +130,4 @@ See [Changelog](https://github.com/anycable/anycable/blob/0-6-stable/CHANGELOG.m
116
130
  [@palkan]: https://github.com/palkan
117
131
  [@sponomarev]: https://github.com/sponomarev
118
132
  [@bibendi]: https://github.com/bibendi
133
+ [@smasry]: https://github.com/smasry
@@ -10,7 +10,7 @@ module AnyCable
10
10
  #
11
11
  # Example:
12
12
  #
13
- # AnyCable.broadast_adapter = :http
13
+ # AnyCable.broadcast_adapter = :http
14
14
  #
15
15
  # It uses configuration from global AnyCable config
16
16
  # by default.
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "nats/client"
5
+ rescue LoadError
6
+ raise "Please, install the nats-pure gem to use NATS broadcast adapter"
7
+ end
8
+
9
+ require "json"
10
+
11
+ module AnyCable
12
+ module BroadcastAdapters
13
+ # NATS adapter for broadcasting.
14
+ #
15
+ # Example:
16
+ #
17
+ # AnyCable.broadcast_adapter = :nats
18
+ #
19
+ # It uses NATS configuration from global AnyCable config
20
+ # by default.
21
+ #
22
+ # You can override these params:
23
+ #
24
+ # AnyCable.broadcast_adapter = :nats, servers: "nats://my_nats:4242", channel: "_any_cable_"
25
+ class Nats < Base
26
+ attr_reader :nats_conn, :channel
27
+
28
+ def initialize(
29
+ channel: AnyCable.config.nats_channel,
30
+ **options
31
+ )
32
+ options = AnyCable.config.to_nats_params.merge(options)
33
+ @nats_conn = ::NATS.connect(nil, options)
34
+ @channel = channel
35
+ end
36
+
37
+ def raw_broadcast(payload)
38
+ nats_conn.publish(channel, payload)
39
+ end
40
+
41
+ def announce!
42
+ logger.info "Broadcasting NATS channel: #{channel}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -3,7 +3,7 @@
3
3
  begin
4
4
  require "redis"
5
5
  rescue LoadError
6
- raise "Please, install redis gem to use Redis broadcast adapter"
6
+ raise "Please, install the redis gem to use Redis broadcast adapter"
7
7
  end
8
8
 
9
9
  require "json"
@@ -14,7 +14,7 @@ module AnyCable
14
14
  #
15
15
  # Example:
16
16
  #
17
- # AnyCable.broadast_adapter = :redis
17
+ # AnyCable.broadcast_adapter = :redis
18
18
  #
19
19
  # It uses Redis configuration from global AnyCable config
20
20
  # by default.
@@ -30,6 +30,7 @@ module AnyCable
30
30
  **options
31
31
  )
32
32
  options = AnyCable.config.to_redis_params.merge(options)
33
+ options[:driver] = :ruby
33
34
  @redis_conn = ::Redis.new(**options)
34
35
  @channel = channel
35
36
  end
data/lib/anycable/cli.rb CHANGED
@@ -65,6 +65,8 @@ module AnyCable
65
65
 
66
66
  check_version!
67
67
 
68
+ configure_middleware!
69
+
68
70
  @server = AnyCable.server_builder.call(config)
69
71
 
70
72
  # Make sure middlewares are not adding after server has started
@@ -119,7 +121,7 @@ module AnyCable
119
121
  def wait_till_terminated
120
122
  self_read = setup_signals
121
123
 
122
- while readable_io = IO.select([self_read]) # rubocop:disable Lint/AssignmentInCondition,Lint/IncompatibleIoSelectWithFiberScheduler
124
+ while readable_io = IO.select([self_read]) # rubocop:disable Lint/AssignmentInCondition
123
125
  signal = readable_io.first[0].gets.strip
124
126
  raise Interrupt, "SIG#{signal} received"
125
127
  end
@@ -265,6 +267,12 @@ module AnyCable
265
267
  )
266
268
  end
267
269
 
270
+ def configure_middleware!
271
+ if config.sid_header_enabled?
272
+ AnyCable.middleware.use(AnyCable::Middlewares::EnvSid)
273
+ end
274
+ end
275
+
268
276
  def parse_gem_options!(args)
269
277
  config.parse_options!(args)
270
278
  rescue OptionParser::InvalidOption => e
@@ -29,6 +29,12 @@ module AnyCable
29
29
  redis_sentinels: nil,
30
30
  redis_channel: "__anycable__",
31
31
 
32
+ ### NATS options
33
+ nats_servers: "nats://localhost:4222",
34
+ nats_channel: "__anycable__",
35
+ nats_dont_randomize_servers: false,
36
+ nats_options: {},
37
+
32
38
  ### HTTP broadcasting options
33
39
  http_broadcast_url: "http://localhost:8090/_broadcast",
34
40
  http_broadcast_secret: nil,
@@ -43,14 +49,22 @@ module AnyCable
43
49
  http_health_path: "/health",
44
50
 
45
51
  ### Misc options
46
- version_check_enabled: true
52
+ version_check_enabled: true,
53
+ sid_header_enabled: true
47
54
  )
48
55
 
49
56
  if respond_to?(:coerce_types)
50
- coerce_types redis_sentinels: {type: nil, array: true}, debug: :boolean, version_check_enabled: :boolean
57
+ coerce_types(
58
+ redis_sentinels: {type: nil, array: true},
59
+ nats_servers: {type: nil, array: true},
60
+ nats_dont_randomize_servers: :boolean,
61
+ debug: :boolean,
62
+ version_check_enabled: :boolean
63
+ )
51
64
  end
52
65
 
53
- flag_options :debug
66
+ flag_options :debug, :nats_dont_randomize_servers
67
+ ignore_options :nats_options
54
68
 
55
69
  on_load do
56
70
  # @type self : AnyCable::Config
@@ -81,6 +95,11 @@ module AnyCable
81
95
  --redis-channel=name Redis channel for broadcasting, default: "__anycable__"
82
96
  --redis-sentinels=<...hosts> Redis Sentinel followers addresses (as a comma-separated list), default: nil
83
97
 
98
+ NATS PUB/SUB
99
+ --nats-servers=<...addresses> NATS servers for pub/sub, default: "nats://localhost:4222"
100
+ --nats-channel=name NATS channel for broadcasting, default: "__anycable__"
101
+ --nats-dont-randomize-servers Pass this option to disable NATS servers randomization during (re-)connect
102
+
84
103
  HTTP PUB/SUB
85
104
  --http-broadcast-url HTTP pub/sub endpoint URL, default: "http://localhost:8090/_broadcast"
86
105
  --http-broadcast-secret HTTP pub/sub authorization secret, default: <none> (disabled)
@@ -106,6 +125,14 @@ module AnyCable
106
125
  end
107
126
  end
108
127
 
128
+ # Build options for NATS.connect
129
+ def to_nats_params
130
+ {
131
+ servers: Array(nats_servers),
132
+ dont_randomize_servers: nats_dont_randomize_servers
133
+ }.merge(nats_options)
134
+ end
135
+
109
136
  # Build HTTP health server parameters
110
137
  def to_http_health_params
111
138
  {
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCable
4
+ module Middlewares
5
+ # Set sid for request.env from metadata
6
+ class EnvSid < AnyCable::Middleware
7
+ def call(_method, request, meta)
8
+ return yield unless meta["sid"]
9
+ request.env.sid = meta["sid"]
10
+
11
+ yield
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/anycable/rpc.rb CHANGED
@@ -88,4 +88,11 @@ module AnyCable
88
88
  class DisconnectResponse
89
89
  include StatusPredicates
90
90
  end
91
+
92
+ # TODO: Move sid to env in the future version of RPC proto
93
+ unless Env.instance_methods(false).include?(:sid)
94
+ class Env
95
+ attr_accessor :sid
96
+ end
97
+ end
91
98
  end
@@ -129,7 +129,8 @@ module AnyCable
129
129
  "rack.url_scheme" => uri.scheme&.sub(/^ws/, "http"),
130
130
  # AnyCable specific fields
131
131
  "anycable.raw_cstate" => request_env.cstate&.to_h,
132
- "anycable.raw_istate" => request_env.istate&.to_h
132
+ "anycable.raw_istate" => request_env.istate&.to_h,
133
+ "anycable.sid" => request_env.sid
133
134
  }.delete_if { |_k, v| v.nil? })
134
135
 
135
136
  env.merge!(build_headers(headers))
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnyCable
4
- VERSION = "1.2.1"
4
+ VERSION = "1.2.4"
5
5
  end
data/lib/anycable.rb CHANGED
@@ -10,6 +10,7 @@ require "anycable/broadcast_adapters"
10
10
  require "anycable/middleware_chain"
11
11
  require "anycable/middlewares/exceptions"
12
12
  require "anycable/middlewares/check_version"
13
+ require "anycable/middlewares/env_sid"
13
14
 
14
15
  require "anycable/socket"
15
16
  require "anycable/rpc"
@@ -0,0 +1,10 @@
1
+ module AnyCable
2
+ module BroadcastAdapters
3
+ class Nats < Base
4
+ attr_reader nats_conn: untyped
5
+ attr_reader channel: String
6
+
7
+ def initialize: (?channel: String channel, **untyped options) -> void
8
+ end
9
+ end
10
+ end
@@ -8,6 +8,14 @@ module AnyCable
8
8
  def redis_sentinels=: (Array[String]) -> void
9
9
  def redis_channel: () -> String
10
10
  def redis_channel=: (String) -> void
11
+ def nats_servers: () -> Array[String]
12
+ def nats_servers=: (Array[String]) -> void
13
+ def nats_channel: () -> String
14
+ def nats_channel=: (String) -> void
15
+ def nats_dont_randomize_servers: () -> bool
16
+ def nats_dont_randomize_servers=: (bool) -> void
17
+ def nats_options: () -> Hash[untyped, untyped]
18
+ def nats_options=: (Hash[untyped, untyped]) -> void
11
19
  def http_broadcast_url: () -> String
12
20
  def http_broadcast_url=: (String) -> void
13
21
  def http_broadcast_secret: () -> String?
@@ -38,6 +46,7 @@ module AnyCable
38
46
  def http_health_port_provided?: () -> bool
39
47
  def to_redis_params: () -> { url: String, sentinels: Array[untyped]?, ssl_params: Hash[Symbol, untyped]? }
40
48
  def to_http_health_params: () -> { port: Integer?, path: String }
49
+ def to_nats_params: () -> Hash[Symbol, untyped]
41
50
 
42
51
  private
43
52
 
@@ -0,0 +1,6 @@
1
+ module AnyCable
2
+ module Middlewares
3
+ class EnvSid < AnyCable::Middleware
4
+ end
5
+ end
6
+ end
data/sig/anycable/rpc.rbs CHANGED
@@ -24,6 +24,7 @@ module AnyCable
24
24
 
25
25
  attr_accessor url: String
26
26
  attr_accessor headers: protoMap
27
+ attr_accessor sid: String?
27
28
 
28
29
  def initialize: (?url: String, ?headers: protoMap, ?cstate: protoMap?, ?istate: protoMap?) -> void
29
30
  end
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.1
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-21 00:00:00.000000000 Z
11
+ date: 2022-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nats-pure
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -157,6 +171,7 @@ files:
157
171
  - lib/anycable/broadcast_adapters.rb
158
172
  - lib/anycable/broadcast_adapters/base.rb
159
173
  - lib/anycable/broadcast_adapters/http.rb
174
+ - lib/anycable/broadcast_adapters/nats.rb
160
175
  - lib/anycable/broadcast_adapters/redis.rb
161
176
  - lib/anycable/cli.rb
162
177
  - lib/anycable/config.rb
@@ -170,6 +185,7 @@ files:
170
185
  - lib/anycable/middleware.rb
171
186
  - lib/anycable/middleware_chain.rb
172
187
  - lib/anycable/middlewares/check_version.rb
188
+ - lib/anycable/middlewares/env_sid.rb
173
189
  - lib/anycable/middlewares/exceptions.rb
174
190
  - lib/anycable/protos/rpc_pb.rb
175
191
  - lib/anycable/rpc.rb
@@ -185,6 +201,7 @@ files:
185
201
  - sig/anycable/broadcast_adapters.rbs
186
202
  - sig/anycable/broadcast_adapters/base.rbs
187
203
  - sig/anycable/broadcast_adapters/http.rbs
204
+ - sig/anycable/broadcast_adapters/nats.rbs
188
205
  - sig/anycable/broadcast_adapters/redis.rbs
189
206
  - sig/anycable/cli.rbs
190
207
  - sig/anycable/config.rbs
@@ -197,6 +214,7 @@ files:
197
214
  - sig/anycable/middleware.rbs
198
215
  - sig/anycable/middleware_chain.rbs
199
216
  - sig/anycable/middlewares/check_version.rbs
217
+ - sig/anycable/middlewares/env_sid.rbs
200
218
  - sig/anycable/middlewares/exceptions.rbs
201
219
  - sig/anycable/rpc.rbs
202
220
  - sig/anycable/rpc/handler.rbs
@@ -223,14 +241,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
241
  requirements:
224
242
  - - ">="
225
243
  - !ruby/object:Gem::Version
226
- version: 2.7.0
244
+ version: 2.6.0
227
245
  required_rubygems_version: !ruby/object:Gem::Requirement
228
246
  requirements:
229
247
  - - ">="
230
248
  - !ruby/object:Gem::Version
231
249
  version: '0'
232
250
  requirements: []
233
- rubygems_version: 3.2.22
251
+ rubygems_version: 3.3.11
234
252
  signing_key:
235
253
  specification_version: 4
236
254
  summary: AnyCable core RPC implementation