graphql-anycable 1.1.0 → 1.1.3

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: 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