graphql-fragment_cache 1.14.0 → 1.16.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: 44be1de2fded16cfd021afebe96ce647616225fdbe5de8b140099d2c1bb16f94
4
- data.tar.gz: 94fb9a82b527c9786d81fed29e821416038c0b20a63f33fe765fc76abf0a9c24
3
+ metadata.gz: 3bcaf1bb938f830b5ae34b7b034e2ccbf8ce139e5da10db08e8ca52b658c0ed3
4
+ data.tar.gz: 5842f5166dc9cf69a276b3dee9836a43b757485ffe46f54031ce42341dfe797a
5
5
  SHA512:
6
- metadata.gz: c10be9f09dcddd09f175452f86071330fe3cb72e9d5875169e20c000372a88ec44e9c9830154e5d2016af177e55852ccf3ae2594e5069e939be4ab0a43676a24
7
- data.tar.gz: 5ded87b46c9757d28ac95028d16f2e2e71c3ed3d5252285898cc033dff835e61bff6aa7777633b8798eed6fb9dcecacf78d0e0623f1952f74139be8b66a9beee
6
+ metadata.gz: e218c2d46cb5cc545d0374c86c64f46380b82a4c31dd67d0dcb06890e23c4156ed16cef838d3965ae54283e28ea7ba155d965920dbc1c9a722a64fff7c174b69
7
+ data.tar.gz: caa35cd10a7c657b838088b0ffd449b981ee3565483691619af1c839a184febccacf19620c31bfee26f434929218e2ecd4478a6edbca7bf97ae3a68245bbe316
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.16.0 (2022-11-06)
6
+
7
+ - [PR#42](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/42) Raise helpful errors when write or write_multi fails ([@DmitryTsepelev][])
8
+ - [PR#86](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/86) Support passing Procs to `cache_key:` ([@jeromedalbert][])
9
+ - [PR#90](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/90) Add option to disable the cache ([@jeromedalbert][])
10
+ - [PR#89](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/89) Use a "graphql" cache namespace by default ([@jeromedalbert][])
11
+
12
+ ## 1.15.0 (2022-10-27)
13
+
14
+ - [PR#43](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/43) Implement `skip_cache_when_query_has_errors` option to skip caching when query was resolved with errors ([@DmitryTsepelev][])
15
+
5
16
  ## 1.14.0 (2022-10-26)
6
17
 
7
18
  - [PR#85](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/85) Support passing Symbols to `if:` and `unless:` ([@palkan][])
data/README.md CHANGED
@@ -72,10 +72,10 @@ Cache keys consist of the following parts: namespace, implicit key, and explicit
72
72
 
73
73
  ### Cache namespace
74
74
 
75
- You can optionally define a namespace that will be prefixed to every cache key:
75
+ The namespace is prefixed to every cached key. The default namespace is `graphql`, which is configurable:
76
76
 
77
77
  ```ruby
78
- GraphQL::FragmentCache.namespace = "my-prefix"
78
+ GraphQL::FragmentCache.namespace = "graphql"
79
79
  ```
80
80
 
81
81
  ### Implicit cache key
@@ -237,6 +237,14 @@ def post(id:)
237
237
  end
238
238
  ```
239
239
 
240
+ If you need more control, you can set `cache_key:` to any custom code:
241
+
242
+ ```ruby
243
+ field :posts,
244
+ Types::Objects::PostType.connection_type,
245
+ cache_fragment: {cache_key: -> { object.posts.maximum(:created_at) }}
246
+ ```
247
+
240
248
  The way cache key part is generated for the passed argument is the following:
241
249
 
242
250
  - Use `object_cache_key: "some_cache_key"` if passed to `cache_fragment`
@@ -424,6 +432,24 @@ end
424
432
 
425
433
  This can reduce a number of cache calls but _increase_ memory usage, because the value returned from cache will be kept in the GraphQL context until the query is fully resolved.
426
434
 
435
+ ## Execution errors and caching
436
+
437
+ Sometimes errors happen during query resolving and it might make sense to skip caching for such queries (for instance, imagine a situation when client has no access to the requested field and the backend returns `{ data: {}, errors: ["you need a permission to fetch orders"] }`). This is how this behavior can be turned on (_it's off by default!_):
438
+
439
+ ```ruby
440
+ GraphQL::FragmentCache.skip_cache_when_query_has_errors = true
441
+ ```
442
+
443
+ As a result, caching will be skipped when `errors` array is not empty.
444
+
445
+ ## Disabling the cache
446
+
447
+ Cache processing can be disabled if needed. For example:
448
+
449
+ ```ruby
450
+ GraphQL::FragmentCache.enabled = false if Rails.env.test?
451
+ ```
452
+
427
453
  ## Limitations
428
454
 
429
455
  1. `Schema#execute`, [graphql-batch](https://github.com/Shopify/graphql-batch) and _graphql-ruby-fragment_cache_ do not [play well](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/issues/45) together. The problem appears when `cache_fragment` is _inside_ the `.then` block:
@@ -4,6 +4,29 @@ module GraphQL
4
4
  module FragmentCache
5
5
  using Ext
6
6
 
7
+ class WriteError < StandardError
8
+ attr_reader :key, :value, :original_error
9
+
10
+ def initialize(original_error, key, value)
11
+ @original_error = original_error
12
+ @key = key
13
+ @value = value
14
+
15
+ super(original_error.message)
16
+ end
17
+ end
18
+
19
+ class WriteMultiError < StandardError
20
+ attr_reader :values, :original_error
21
+
22
+ def initialize(original_error, values)
23
+ @original_error = original_error
24
+ @values = values
25
+
26
+ super(original_error.message)
27
+ end
28
+ end
29
+
7
30
  # Saves resolved fragment values to cache store
8
31
  module Cacher
9
32
  class << self
@@ -22,13 +45,20 @@ module GraphQL
22
45
  def batched_persist(query)
23
46
  select_valid_fragments(query).group_by(&:options).each do |options, group|
24
47
  hash = group.map { |fragment| [fragment.cache_key, fragment.value] }.to_h
25
- FragmentCache.cache_store.write_multi(hash, **options)
48
+
49
+ begin
50
+ FragmentCache.cache_store.write_multi(hash, **options)
51
+ rescue => e
52
+ raise WriteMultiError.new(e, hash)
53
+ end
26
54
  end
27
55
  end
28
56
 
29
57
  def persist(query)
30
58
  select_valid_fragments(query).each do |fragment|
31
59
  FragmentCache.cache_store.write(fragment.cache_key, fragment.value, **fragment.options)
60
+ rescue => e
61
+ raise WriteError.new(e, fragment.cache_key, fragment.value)
32
62
  end
33
63
  end
34
64
 
@@ -70,6 +70,8 @@ module GraphQL
70
70
  object.object
71
71
  elsif @cache_key == :value
72
72
  resolved_value = yield(object, arguments)
73
+ elsif @cache_key.is_a?(Proc)
74
+ object.instance_exec(&@cache_key)
73
75
  end
74
76
 
75
77
  cache_fragment_options = @cache_options.merge(object: object_for_key)
@@ -25,6 +25,9 @@ module GraphQL
25
25
 
26
26
  def cache_fragment(object_to_cache = NO_OBJECT, **options, &block)
27
27
  raise ArgumentError, "Block or argument must be provided" unless block_given? || object_to_cache != NO_OBJECT
28
+ unless GraphQL::FragmentCache.enabled
29
+ return block_given? ? block.call : object_to_cache
30
+ end
28
31
 
29
32
  unless options.delete(:default_options_merged)
30
33
  options = GraphQL::FragmentCache.default_options.merge(options)
@@ -13,10 +13,15 @@ module GraphQL
13
13
  end
14
14
 
15
15
  def after_query(query)
16
- return unless query.valid?
16
+ return if skip_caching?(query)
17
17
 
18
18
  Cacher.call(query)
19
19
  end
20
+
21
+ def skip_caching?(query)
22
+ !query.valid? ||
23
+ GraphQL::FragmentCache.skip_cache_when_query_has_errors? && query.context.errors.any?
24
+ end
20
25
  end
21
26
  end
22
27
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module FragmentCache
5
- VERSION = "1.14.0"
5
+ VERSION = "1.16.0"
6
6
  end
7
7
  end
@@ -22,9 +22,12 @@ module GraphQL
22
22
  module FragmentCache
23
23
  class << self
24
24
  attr_reader :cache_store
25
+ attr_accessor :enabled
25
26
  attr_accessor :namespace
26
27
  attr_accessor :default_options
27
28
 
29
+ attr_accessor :skip_cache_when_query_has_errors
30
+
28
31
  def use(schema_defn, options = {})
29
32
  verify_interpreter_and_analysis!(schema_defn)
30
33
 
@@ -52,6 +55,8 @@ module GraphQL
52
55
  @cache_store = store
53
56
  end
54
57
 
58
+ alias skip_cache_when_query_has_errors? skip_cache_when_query_has_errors
59
+
55
60
  def graphql_ruby_before_2_0?
56
61
  check_graphql_version "< 2.0.0"
57
62
  end
@@ -83,7 +88,10 @@ module GraphQL
83
88
  end
84
89
 
85
90
  self.cache_store = MemoryStore.new
91
+ self.enabled = true
92
+ self.namespace = "graphql"
86
93
  self.default_options = {}
94
+ self.skip_cache_when_query_has_errors = false
87
95
  end
88
96
  end
89
97
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-fragment_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-26 00:00:00.000000000 Z
11
+ date: 2022-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -220,7 +220,7 @@ metadata:
220
220
  homepage_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
221
221
  source_code_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
222
222
  changelog_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/CHANGELOG.md
223
- post_install_message:
223
+ post_install_message:
224
224
  rdoc_options: []
225
225
  require_paths:
226
226
  - lib
@@ -235,8 +235,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
237
  requirements: []
238
- rubygems_version: 3.1.6
239
- signing_key:
238
+ rubygems_version: 3.2.33
239
+ signing_key:
240
240
  specification_version: 4
241
241
  summary: Fragment cache for graphql-ruby
242
242
  test_files: []