graphql-anycable 1.1.0 → 1.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 335a3ba62f65f0d6dfdd5eab2e1361382d192b5fbc910c591ced6f78296fb4ff
4
- data.tar.gz: 9f392057c605fc0b74d6ea2c940409540b87e25ddb0a6dee34e47ad3929f652a
3
+ metadata.gz: fe8111474650b5580715d08c4122d70db3dcf45a4e1760d561e05119124181f7
4
+ data.tar.gz: 02e62b9ab477143af5889de901181de56aab1d88ec6a174041f4a2307090bbb0
5
5
  SHA512:
6
- metadata.gz: 55b8fbf37efbdeff43beb7266ed627491b1a592f9cfe7e803dfd420b49d988a8057cb4ad7df7dea916df4f4c555868e29bace42cc76d2ae692755421a05f8bd5
7
- data.tar.gz: d0665b9ec01879f5898c7638a9325c156c2665966552edc20cd013d3dfefbbbbada8e7e22d32e31ce7d8e6e0f59576c9a377ff92ffd1eb8e674e4cef533c7659
6
+ metadata.gz: 9ff1cfaa560fc9361704545d6c071658e8847d07b8d37f72b2680396046788f5c65ce3d63a026b1af10192a96684a54e078d1b7a5572e13bf778d52fd1e5fd53
7
+ data.tar.gz: bc67b3fb5b20f6e0ec06637b40410ecdd6420d58f7cb4eb3eaa610a4258fda1139d2cfd24237280e1af74893c06a363b6e6611ae5c0146439c4d9094cb07b0c6
@@ -10,50 +10,31 @@ on:
10
10
 
11
11
  jobs:
12
12
  test:
13
- name: "GraphQL-Ruby ${{ matrix.graphql }} (interpreter: ${{ matrix.interpreter }}) with AnyCable ${{ matrix.anycable }} on Ruby ${{ matrix.ruby }}"
13
+ name: "GraphQL-Ruby ${{ matrix.graphql }} on Ruby ${{ matrix.ruby }} (use_client_id: ${{ matrix.client_id }})"
14
14
  runs-on: ubuntu-latest
15
15
  strategy:
16
16
  fail-fast: false
17
17
  matrix:
18
18
  include:
19
+ - ruby: "3.1"
20
+ graphql: '~> 2.0.0'
21
+ client_id: 'false'
22
+ anycable_rails: '~> 1.3'
19
23
  - ruby: "3.0"
20
- graphql: '~> 1.12.0'
21
- anycable: '~> 1.1.0'
22
- interpreter: yes
23
- - ruby: "3.0"
24
- graphql: '~> 1.12.0'
25
- anycable: '~> 1.1.0'
26
- interpreter: no
27
- - ruby: 2.7
28
- graphql: '~> 1.12.0'
29
- anycable: '~> 1.1.0'
30
- interpreter: yes
24
+ graphql: '~> 1.13.0'
25
+ client_id: 'false'
26
+ anycable_rails: '~> 1.2.0'
31
27
  - ruby: 2.7
32
28
  graphql: '~> 1.12.0'
33
- anycable: '~> 1.1.0'
34
- interpreter: no
35
- - ruby: 2.6
36
- graphql: '~> 1.11.0'
37
- anycable: '~> 1.0.0'
38
- interpreter: yes
39
- - ruby: 2.6
40
- graphql: '~> 1.11.0'
41
- anycable: '~> 1.0.0'
42
- interpreter: no
43
- - ruby: 2.5
44
- graphql: '~> 1.11.0'
45
- anycable: '~> 1.0.0'
46
- interpreter: yes
47
- - ruby: 2.5
48
- graphql: '~> 1.11.0'
49
- anycable: '~> 1.0.0'
50
- interpreter: no
29
+ client_id: 'true'
30
+ anycable_rails: '~> 1.1.0'
51
31
  container:
52
32
  image: ruby:${{ matrix.ruby }}
53
33
  env:
54
34
  CI: true
55
35
  GRAPHQL_RUBY_VERSION: ${{ matrix.graphql }}
56
- ANYCABLE_VERSION: ${{ matrix.anycable }}
36
+ ANYCABLE_RAILS_VERSION: ${{ matrix.anycable_rails }}
37
+ GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID: ${{ matrix.client_id }}
57
38
  steps:
58
39
  - uses: actions/checkout@v2
59
40
  - uses: actions/cache@v2
@@ -71,6 +52,4 @@ jobs:
71
52
  bundle install
72
53
  bundle update
73
54
  - name: Run RSpec
74
- env:
75
- GRAPHQL_RUBY_INTERPRETER: ${{ matrix.interpreter }}
76
55
  run: bundle exec rspec
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.3 - 2022-03-11
11
+
12
+ ### Changed
13
+
14
+ - Allow using graphql-anycable with GraphQL-Ruby 2.x (it seem to be already compatible). [@Envek]
15
+
16
+ ## 1.1.2 - 2022-03-11
17
+
18
+ ### Fixed
19
+
20
+ - AnyCable 1.3.0 compatibility. [@palkan] [#21](https://github.com/anycable/graphql-anycable/pull/21)
21
+ - Redis.rb 5.0 compatibility. [@palkan] [#21](https://github.com/anycable/graphql-anycable/pull/21)
22
+
23
+ ## 1.1.1 - 2021-12-06
24
+
25
+ ### Fixed
26
+
27
+ - Handling of buggy istate values on unsubscribe (when `use_client_provided_uniq_id: false`). [@palkan] [#20](https://github.com/anycable/graphql-anycable/pull/20)
28
+ - A bug when `#unsubscribe` happens before `#execute`. [@palkan] [#20](https://github.com/anycable/graphql-anycable/pull/20)
29
+
10
30
  ## 1.1.0 - 2021-11-17
11
31
 
12
32
  ### Added
@@ -142,3 +162,4 @@ Initial version: store subscriptions on redis, re-execute queries in sync. [@Env
142
162
  [@bibendi]: https://github.com/bibendi "Misha Merkushin"
143
163
  [@FX-HAO]: https://github.com/FX-HAO "Fuxin Hao"
144
164
  [@Envek]: https://github.com/Envek "Andrey Novikov"
165
+ [@palkan]: https://github.com/palkan "Vladimir Dementyev"
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ gemspec
9
9
 
10
10
  gem "graphql", ENV.fetch("GRAPHQL_RUBY_VERSION", "~> 1.12")
11
11
  gem "anycable", ENV.fetch("ANYCABLE_VERSION", "~> 1.0")
12
+ gem "anycable-rails", ENV.fetch("ANYCABLE_RAILS_VERSION", "~> 1.2")
12
13
 
13
14
  group :development, :test do
14
15
  gem "pry"
data/README.md CHANGED
@@ -111,8 +111,8 @@ By default all fields are marked as _not safe for broadcasting_. If a subscripti
111
111
 
112
112
  ```ruby
113
113
  class MySchema < GraphQL::Schema
114
- use GraphQL::Execution::Interpreter # Required for graphql-ruby before 1.12.4
115
- use GraphQL::Analysis::AST
114
+ use GraphQL::Execution::Interpreter # Required for graphql-ruby before 1.12. Remove it when upgrading to 2.0
115
+ use GraphQL::Analysis::AST # Required for graphql-ruby before 1.12. Remove it when upgrading to 2.0
116
116
  use GraphQL::AnyCable, broadcast: true, default_broadcastable: true
117
117
 
118
118
  subscription SubscriptionType
@@ -144,7 +144,7 @@ GraphQL-AnyCable uses [anyway_config] to configure itself. There are several pos
144
144
  GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID=false
145
145
  ```
146
146
 
147
- 2. YAML configuration files:
147
+ 2. YAML configuration files (note that this is `config/graphql_anycable.yml`, *not* `config/anycable.yml`):
148
148
 
149
149
  ```yaml
150
150
  # config/graphql_anycable.yml
@@ -215,6 +215,39 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
215
215
 
216
216
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
217
217
 
218
+ ### Releasing new versions
219
+
220
+ 1. Bump version number in `lib/graphql/anycable/version.rb`
221
+
222
+ In case of pre-releases keep in mind [rubygems/rubygems#3086](https://github.com/rubygems/rubygems/issues/3086) and check version with command like `Gem::Version.new(AfterCommitEverywhere::VERSION).to_s`
223
+
224
+ 2. Fill `CHANGELOG.md` with missing changes, add header with version and date.
225
+
226
+ 3. Make a commit:
227
+
228
+ ```sh
229
+ git add lib/graphql/anycable/version.rb CHANGELOG.md
230
+ version=$(ruby -r ./lib/graphql/anycable/version.rb -e "puts Gem::Version.new(GraphQL::AnyCable::VERSION)")
231
+ git commit --message="${version}: " --edit
232
+ ```
233
+
234
+ 4. Create annotated tag:
235
+
236
+ ```sh
237
+ git tag v${version} --annotate --message="${version}: " --edit --sign
238
+ ```
239
+
240
+ 5. Fill version name into subject line and (optionally) some description (list of changes will be taken from `CHANGELOG.md` and appended automatically)
241
+
242
+ 6. Push it:
243
+
244
+ ```sh
245
+ git push --follow-tags
246
+ ```
247
+
248
+ 7. GitHub Actions will create a new release, build and push gem into [rubygems.org](https://rubygems.org)! You're done!
249
+
250
+
218
251
  ## Contributing
219
252
 
220
253
  Bug reports and pull requests are welcome on GitHub at https://github.com/Envek/graphql-anycable.
@@ -28,11 +28,14 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_dependency "anycable", "~> 1.0"
30
30
  spec.add_dependency "anyway_config", ">= 1.3", "< 3"
31
- spec.add_dependency "graphql", "~> 1.11"
31
+ spec.add_dependency "graphql", ">= 1.11", "< 3"
32
32
  spec.add_dependency "redis", ">= 4.2.0"
33
33
 
34
+ spec.add_development_dependency "anycable-rails"
34
35
  spec.add_development_dependency "bundler", "~> 2.0"
35
36
  spec.add_development_dependency "fakeredis"
37
+ spec.add_development_dependency "rack"
38
+ spec.add_development_dependency "railties"
36
39
  spec.add_development_dependency "rake", ">= 12.3.3"
37
40
  spec.add_development_dependency "rspec", "~> 3.0"
38
41
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module AnyCable
5
- VERSION = "1.1.0"
5
+ VERSION = "1.1.3"
6
6
  end
7
7
  end
@@ -79,9 +79,9 @@ module GraphQL
79
79
  return if fingerprints.empty?
80
80
 
81
81
  fingerprint_subscription_ids = Hash[fingerprints.zip(
82
- redis.pipelined do
82
+ redis.pipelined do |pipeline|
83
83
  fingerprints.map do |fingerprint|
84
- redis.smembers(SUBSCRIPTIONS_PREFIX + fingerprint)
84
+ pipeline.smembers(SUBSCRIPTIONS_PREFIX + fingerprint)
85
85
  end
86
86
  end
87
87
  )]
@@ -160,16 +160,16 @@ module GraphQL
160
160
  events: events.map { |e| [e.topic, e.fingerprint] }.to_h.to_json,
161
161
  }
162
162
 
163
- redis.multi do
164
- redis.sadd(CHANNEL_PREFIX + channel_uniq_id, subscription_id)
165
- redis.mapped_hmset(SUBSCRIPTION_PREFIX + subscription_id, data)
163
+ redis.multi do |pipeline|
164
+ pipeline.sadd(CHANNEL_PREFIX + channel_uniq_id, subscription_id)
165
+ pipeline.mapped_hmset(SUBSCRIPTION_PREFIX + subscription_id, data)
166
166
  events.each do |event|
167
- redis.zincrby(FINGERPRINTS_PREFIX + event.topic, 1, event.fingerprint)
168
- redis.sadd(SUBSCRIPTIONS_PREFIX + event.fingerprint, subscription_id)
167
+ pipeline.zincrby(FINGERPRINTS_PREFIX + event.topic, 1, event.fingerprint)
168
+ pipeline.sadd(SUBSCRIPTIONS_PREFIX + event.fingerprint, subscription_id)
169
169
  end
170
170
  next unless config.subscription_expiration_seconds
171
- redis.expire(CHANNEL_PREFIX + channel_uniq_id, config.subscription_expiration_seconds)
172
- redis.expire(SUBSCRIPTION_PREFIX + subscription_id, config.subscription_expiration_seconds)
171
+ pipeline.expire(CHANNEL_PREFIX + channel_uniq_id, config.subscription_expiration_seconds)
172
+ pipeline.expire(SUBSCRIPTION_PREFIX + subscription_id, config.subscription_expiration_seconds)
173
173
  end
174
174
  end
175
175
 
@@ -191,19 +191,19 @@ module GraphQL
191
191
  events = redis.hget(SUBSCRIPTION_PREFIX + subscription_id, :events)
192
192
  events = events ? JSON.parse(events) : {}
193
193
  fingerprint_subscriptions = {}
194
- redis.pipelined do
194
+ redis.pipelined do |pipeline|
195
195
  events.each do |topic, fingerprint|
196
- redis.srem(SUBSCRIPTIONS_PREFIX + fingerprint, subscription_id)
197
- score = redis.zincrby(FINGERPRINTS_PREFIX + topic, -1, fingerprint)
196
+ pipeline.srem(SUBSCRIPTIONS_PREFIX + fingerprint, subscription_id)
197
+ score = pipeline.zincrby(FINGERPRINTS_PREFIX + topic, -1, fingerprint)
198
198
  fingerprint_subscriptions[FINGERPRINTS_PREFIX + topic] = score
199
199
  end
200
200
  # Delete subscription itself
201
- redis.del(SUBSCRIPTION_PREFIX + subscription_id)
201
+ pipeline.del(SUBSCRIPTION_PREFIX + subscription_id)
202
202
  end
203
203
  # Clean up fingerprints that doesn't have any subscriptions left
204
- redis.pipelined do
204
+ redis.pipelined do |pipeline|
205
205
  fingerprint_subscriptions.each do |key, score|
206
- redis.zremrangebyscore(key, '-inf', '0') if score.value.zero?
206
+ pipeline.zremrangebyscore(key, '-inf', '0') if score.value.zero?
207
207
  end
208
208
  end
209
209
  delete_legacy_subscription(subscription_id)
@@ -225,6 +225,10 @@ module GraphQL
225
225
  def delete_channel_subscriptions(channel_or_id)
226
226
  # For backward compatibility
227
227
  channel_id = channel_or_id.is_a?(String) ? channel_or_id : read_subscription_id(channel_or_id)
228
+
229
+ # Missing in case disconnect happens before #execute
230
+ return unless channel_id
231
+
228
232
  redis.smembers(CHANNEL_PREFIX + channel_id).each do |subscription_id|
229
233
  delete_subscription(subscription_id)
230
234
  end
@@ -240,13 +244,30 @@ module GraphQL
240
244
  def read_subscription_id(channel)
241
245
  return channel.instance_variable_get(:@__sid__) if channel.instance_variable_defined?(:@__sid__)
242
246
 
243
- channel.instance_variable_set(:@__sid__, channel.connection.socket.istate["sid"])
247
+ istate = fetch_channel_istate(channel)
248
+
249
+ return unless istate
250
+
251
+ channel.instance_variable_set(:@__sid__, istate["sid"])
244
252
  end
245
253
 
246
254
  def write_subscription_id(channel, val)
247
- channel.connection.socket.istate["sid"] = val
255
+ channel.connection.anycable_socket.istate["sid"] = val
248
256
  channel.instance_variable_set(:@__sid__, val)
249
257
  end
258
+
259
+ def fetch_channel_istate(channel)
260
+ # For Rails integration
261
+ return channel.__istate__ if channel.respond_to?(:__istate__)
262
+
263
+ return unless channel.connection.socket.istate
264
+
265
+ if channel.connection.socket.istate[channel.identifier]
266
+ JSON.parse(channel.connection.socket.istate[channel.identifier])
267
+ else
268
+ channel.connection.socket.istate
269
+ end
270
+ end
250
271
  end
251
272
  end
252
273
  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.1.0
4
+ version: 1.1.3
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-17 00:00:00.000000000 Z
11
+ date: 2022-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anycable
@@ -48,16 +48,22 @@ dependencies:
48
48
  name: graphql
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '1.11'
54
+ - - "<"
55
+ - !ruby/object:Gem::Version
56
+ version: '3'
54
57
  type: :runtime
55
58
  prerelease: false
56
59
  version_requirements: !ruby/object:Gem::Requirement
57
60
  requirements:
58
- - - "~>"
61
+ - - ">="
59
62
  - !ruby/object:Gem::Version
60
63
  version: '1.11'
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: '3'
61
67
  - !ruby/object:Gem::Dependency
62
68
  name: redis
63
69
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +78,20 @@ dependencies:
72
78
  - - ">="
73
79
  - !ruby/object:Gem::Version
74
80
  version: 4.2.0
81
+ - !ruby/object:Gem::Dependency
82
+ name: anycable-rails
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
75
95
  - !ruby/object:Gem::Dependency
76
96
  name: bundler
77
97
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +120,34 @@ dependencies:
100
120
  - - ">="
101
121
  - !ruby/object:Gem::Version
102
122
  version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: rack
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: railties
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
103
151
  - !ruby/object:Gem::Dependency
104
152
  name: rake
105
153
  requirement: !ruby/object:Gem::Requirement