graphql-anycable 1.0.1 → 1.1.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: 2ff33e113bf80dad3da7cab49606e37f7b3b69783ce4e8b2bb0466bf3e636881
4
- data.tar.gz: 6c9c58824c29cf9d35e7dc82c70c32b8e398c5482847f888133de5e9fb5ebdb9
3
+ metadata.gz: 335a3ba62f65f0d6dfdd5eab2e1361382d192b5fbc910c591ced6f78296fb4ff
4
+ data.tar.gz: 9f392057c605fc0b74d6ea2c940409540b87e25ddb0a6dee34e47ad3929f652a
5
5
  SHA512:
6
- metadata.gz: 11f689864709223c38a4441b2546f285389ff7d32b694cc983ebda2cc3e829b271686eb25e2d2ca3df3bafa36d2b12ec61b6cb043c28b1b11b98683efb21c2d8
7
- data.tar.gz: d973bb2885f9991b3be3fb13f0c8fec2c7815b67b993ced900d53812d0b661433f3db99cf193ee2b827c57ab59ea1d7111c34d6c8a8cf1923f8b01dfedebc34a
6
+ metadata.gz: 55b8fbf37efbdeff43beb7266ed627491b1a592f9cfe7e803dfd420b49d988a8057cb4ad7df7dea916df4f4c555868e29bace42cc76d2ae692755421a05f8bd5
7
+ data.tar.gz: d0665b9ec01879f5898c7638a9325c156c2665966552edc20cd013d3dfefbbbbada8e7e22d32e31ce7d8e6e0f59576c9a377ff92ffd1eb8e674e4cef533c7659
@@ -18,19 +18,19 @@ jobs:
18
18
  include:
19
19
  - ruby: "3.0"
20
20
  graphql: '~> 1.12.0'
21
- anycable: '~> 1.0.0'
21
+ anycable: '~> 1.1.0'
22
22
  interpreter: yes
23
23
  - ruby: "3.0"
24
24
  graphql: '~> 1.12.0'
25
- anycable: '~> 1.0.0'
25
+ anycable: '~> 1.1.0'
26
26
  interpreter: no
27
27
  - ruby: 2.7
28
28
  graphql: '~> 1.12.0'
29
- anycable: '~> 1.0.0'
29
+ anycable: '~> 1.1.0'
30
30
  interpreter: yes
31
31
  - ruby: 2.7
32
32
  graphql: '~> 1.12.0'
33
- anycable: '~> 1.0.0'
33
+ anycable: '~> 1.1.0'
34
34
  interpreter: no
35
35
  - ruby: 2.6
36
36
  graphql: '~> 1.11.0'
data/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 1.1.0 - 2021-11-17
11
+
12
+ ### Added
13
+
14
+ - Support for generating unique channel IDs server-side and storing them in the channel states.
15
+
16
+ Currently, we rely on `params["channelId"]` to track subscriptions. This value is random when using `graphql-ruby` JS client, but is not guaranteed to be random in general.
17
+
18
+ Now you can opt-in to use server-side IDs by specifying `use_client_provided_uniq_id: false` in YAML config or thru the `GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID=false` env var.
19
+
20
+ NOTE: Relying on client-side IDs is deprecated and will be removed in the future versions.
21
+
22
+ You must also update your cleanup code in the `Channel#unsubscribed`:
23
+
24
+ ```diff
25
+ - channel_id = params.fetch("channelId")
26
+ - MySchema.subscriptions.delete_channel_subscriptions(channel_id)
27
+ + MySchema.subscriptions.delete_channel_subscriptions(self)
28
+ ```
29
+
10
30
  ## 1.0.1 - 2021-04-16
11
31
 
12
32
  ### Added
data/README.md CHANGED
@@ -77,8 +77,7 @@ Or install it yourself as:
77
77
  end
78
78
 
79
79
  def unsubscribed
80
- channel_id = params.fetch("channelId")
81
- MySchema.subscriptions.delete_channel_subscriptions(channel_id)
80
+ MySchema.subscriptions.delete_channel_subscriptions(self)
82
81
  end
83
82
 
84
83
  private
@@ -142,6 +141,7 @@ GraphQL-AnyCable uses [anyway_config] to configure itself. There are several pos
142
141
  GRAPHQL_ANYCABLE_SUBSCRIPTION_EXPIRATION_SECONDS=604800
143
142
  GRAPHQL_ANYCABLE_USE_REDIS_OBJECT_ON_CLEANUP=true
144
143
  GRAPHQL_ANYCABLE_HANDLE_LEGACY_SUBSCRIPTIONS=false
144
+ GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID=false
145
145
  ```
146
146
 
147
147
  2. YAML configuration files:
@@ -152,6 +152,7 @@ GraphQL-AnyCable uses [anyway_config] to configure itself. There are several pos
152
152
  subscription_expiration_seconds: 300 # 5 minutes
153
153
  use_redis_object_on_cleanup: false # For restricted redis installations
154
154
  handle_legacy_subscriptions: false # For seamless upgrade from pre-1.0 versions
155
+ use_client_provided_uniq_id: false # To avoid problems with non-uniqueness of Apollo channel identifiers
155
156
  ```
156
157
 
157
158
  3. Configuration from your application code:
@@ -11,6 +11,15 @@ module GraphQL
11
11
  attr_config subscription_expiration_seconds: nil
12
12
  attr_config use_redis_object_on_cleanup: true
13
13
  attr_config handle_legacy_subscriptions: false
14
+ attr_config use_client_provided_uniq_id: true
15
+
16
+ on_load do
17
+ next unless use_client_provided_uniq_id?
18
+
19
+ warn "[Deprecated] Using client provided channel uniq IDs could lead to unexpected behaviour, " \
20
+ " please, set GraphQL::AnyCable.config.use_client_provided_uniq_id = false or GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID=false, " \
21
+ " and update the `#unsubscribed` callback code according to the latest docs."
22
+ end
14
23
  end
15
24
  end
16
25
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module AnyCable
5
- VERSION = "1.0.1"
5
+ VERSION = "1.1.0"
6
6
  end
7
7
  end
@@ -45,8 +45,7 @@ require "graphql/anycable/errors"
45
45
  # end
46
46
  #
47
47
  # def unsubscribed
48
- # channel_id = params.fetch("channelId")
49
- # MySchema.subscriptions.delete_channel_subscriptions(channel_id)
48
+ # MySchema.subscriptions.delete_channel_subscriptions(self)
50
49
  # end
51
50
  # end
52
51
  #
@@ -143,6 +142,12 @@ module GraphQL
143
142
 
144
143
  raise GraphQL::AnyCable::ChannelConfigurationError unless channel
145
144
 
145
+ channel_uniq_id = config.use_client_provided_uniq_id? ? channel.params["channelId"] : subscription_id
146
+
147
+ # Store subscription_id in the channel state to cleanup on disconnect
148
+ write_subscription_id(channel, channel_uniq_id)
149
+
150
+
146
151
  events.each do |event|
147
152
  channel.stream_from(SUBSCRIPTIONS_PREFIX + event.fingerprint)
148
153
  end
@@ -156,14 +161,14 @@ module GraphQL
156
161
  }
157
162
 
158
163
  redis.multi do
159
- redis.sadd(CHANNEL_PREFIX + channel.params["channelId"], subscription_id)
164
+ redis.sadd(CHANNEL_PREFIX + channel_uniq_id, subscription_id)
160
165
  redis.mapped_hmset(SUBSCRIPTION_PREFIX + subscription_id, data)
161
166
  events.each do |event|
162
167
  redis.zincrby(FINGERPRINTS_PREFIX + event.topic, 1, event.fingerprint)
163
168
  redis.sadd(SUBSCRIPTIONS_PREFIX + event.fingerprint, subscription_id)
164
169
  end
165
170
  next unless config.subscription_expiration_seconds
166
- redis.expire(CHANNEL_PREFIX + channel.params["channelId"], config.subscription_expiration_seconds)
171
+ redis.expire(CHANNEL_PREFIX + channel_uniq_id, config.subscription_expiration_seconds)
167
172
  redis.expire(SUBSCRIPTION_PREFIX + subscription_id, config.subscription_expiration_seconds)
168
173
  end
169
174
  end
@@ -217,7 +222,9 @@ module GraphQL
217
222
  end
218
223
 
219
224
  # The channel was closed, forget about it and its subscriptions
220
- def delete_channel_subscriptions(channel_id)
225
+ def delete_channel_subscriptions(channel_or_id)
226
+ # For backward compatibility
227
+ channel_id = channel_or_id.is_a?(String) ? channel_or_id : read_subscription_id(channel_or_id)
221
228
  redis.smembers(CHANNEL_PREFIX + channel_id).each do |subscription_id|
222
229
  delete_subscription(subscription_id)
223
230
  end
@@ -229,6 +236,17 @@ module GraphQL
229
236
  def anycable
230
237
  @anycable ||= ::AnyCable.broadcast_adapter
231
238
  end
239
+
240
+ def read_subscription_id(channel)
241
+ return channel.instance_variable_get(:@__sid__) if channel.instance_variable_defined?(:@__sid__)
242
+
243
+ channel.instance_variable_set(:@__sid__, channel.connection.socket.istate["sid"])
244
+ end
245
+
246
+ def write_subscription_id(channel, val)
247
+ channel.connection.socket.istate["sid"] = val
248
+ channel.instance_variable_set(:@__sid__, val)
249
+ end
232
250
  end
233
251
  end
234
252
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-anycable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Novikov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-16 00:00:00.000000000 Z
11
+ date: 2021-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anycable