graphql-anycable 1.0.1 → 1.1.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/.github/workflows/test.yml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +3 -2
- data/lib/graphql/anycable/config.rb +9 -0
- data/lib/graphql/anycable/version.rb +1 -1
- data/lib/graphql/subscriptions/anycable_subscriptions.rb +23 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 335a3ba62f65f0d6dfdd5eab2e1361382d192b5fbc910c591ced6f78296fb4ff
|
4
|
+
data.tar.gz: 9f392057c605fc0b74d6ea2c940409540b87e25ddb0a6dee34e47ad3929f652a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55b8fbf37efbdeff43beb7266ed627491b1a592f9cfe7e803dfd420b49d988a8057cb4ad7df7dea916df4f4c555868e29bace42cc76d2ae692755421a05f8bd5
|
7
|
+
data.tar.gz: d0665b9ec01879f5898c7638a9325c156c2665966552edc20cd013d3dfefbbbbada8e7e22d32e31ce7d8e6e0f59576c9a377ff92ffd1eb8e674e4cef533c7659
|
data/.github/workflows/test.yml
CHANGED
@@ -18,19 +18,19 @@ jobs:
|
|
18
18
|
include:
|
19
19
|
- ruby: "3.0"
|
20
20
|
graphql: '~> 1.12.0'
|
21
|
-
anycable: '~> 1.
|
21
|
+
anycable: '~> 1.1.0'
|
22
22
|
interpreter: yes
|
23
23
|
- ruby: "3.0"
|
24
24
|
graphql: '~> 1.12.0'
|
25
|
-
anycable: '~> 1.
|
25
|
+
anycable: '~> 1.1.0'
|
26
26
|
interpreter: no
|
27
27
|
- ruby: 2.7
|
28
28
|
graphql: '~> 1.12.0'
|
29
|
-
anycable: '~> 1.
|
29
|
+
anycable: '~> 1.1.0'
|
30
30
|
interpreter: yes
|
31
31
|
- ruby: 2.7
|
32
32
|
graphql: '~> 1.12.0'
|
33
|
-
anycable: '~> 1.
|
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
|
-
|
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
|
@@ -45,8 +45,7 @@ require "graphql/anycable/errors"
|
|
45
45
|
# end
|
46
46
|
#
|
47
47
|
# def unsubscribed
|
48
|
-
#
|
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 +
|
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 +
|
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(
|
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
|
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-
|
11
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: anycable
|