graphql-fragment_cache 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8454e3e398cc31081e2b17fb4a9b9e971cfbd1da05bce06149e419bb0e6b6b36
4
- data.tar.gz: f654d30606764307daad38b45921533edba92fa2cd95a75556488985bd78a590
3
+ metadata.gz: dab2cb1f4c27251da27c938bd8a0392f3ad0edcb5c54ba1d7d83d9e2f9c4b12b
4
+ data.tar.gz: 8e5323ed6bf476d185c993b8165e292d4d7e70df56fa1ae1ad32da2ae7bc0880
5
5
  SHA512:
6
- metadata.gz: 3a573a48cfe5b5d1beebd665c09b8adc4fe7d7a4bb08b29cc923c2434d921c0e9eb2c46b317d4d44367e46d0afafd2a686a0186cfb68f50459eaad2707f3da72
7
- data.tar.gz: 2db445bfbf4ef1cd56d715e586a6c0b748695e022ac55d94bc8bd52171221902fa562426c8a53cadb2e7d0ee7667dd866f27106fb3901247932e1b1a2e3320b6
6
+ metadata.gz: 90eebb6973db225980926d330d93ca70a50768279bb727cf702f1bd905628cf7969e1af5025a6fefb1f9785d1fc008fd560d236fbe6315821a6dd2f92243ef56
7
+ data.tar.gz: b26090f37a4b20ce45a256880b708c17a77871d8e8f5d95c1b34f171062306332f1bf9a549ab92bce5a326a2327d5b8a4f8106e2b2b4ac338bbd257cec8e6a21
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.4.0 (2020-12-03)
6
+
7
+ - [PR#41](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/41) Add `keep_in_context` option ([@DmitryTsepelev][])
8
+
5
9
  ## 1.3.0 (2020-11-25)
6
10
 
7
11
  - [PR#39](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/39) Implement `path_cache_key` option ([@DmitryTsepelev][])
data/README.md CHANGED
@@ -314,6 +314,24 @@ end
314
314
 
315
315
  With this approach you can use `#cache_fragment` in any place you have an access to the `context`. When context is not available, the error `cannot find context, please pass it explicitly` will be thrown.
316
316
 
317
+ ## In–memory fragments
318
+
319
+ If you have a fragment that accessed from multiple times (e.g., if you have a list of items that belong to the same owner, and owner is cached), you can avoid multiple cache reads by using `:keep_in_context` option:
320
+
321
+ ```ruby
322
+ class QueryType < BaseObject
323
+ field :post, PostType, null: true do
324
+ argument :id, ID, required: true
325
+ end
326
+
327
+ def post(id:)
328
+ cache_fragment(keep_in_context: true, expires_in: 5.minutes) { Post.find(id) }
329
+ end
330
+ end
331
+ ```
332
+
333
+ 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.
334
+
317
335
  ## Limitations
318
336
 
319
337
  Caching does not work for Union types, because of the `Lookahead` implementation: it requires the exact type to be passed to the `selection` method (you can find the [discussion](https://github.com/rmosolgo/graphql-ruby/pull/3007) here). This method is used for cache key building, and I haven't found a workaround yet ([PR in progress](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/30)). If you get `Failed to look ahead the field` error — please pass `query_cache_key` explicitly:
@@ -13,6 +13,10 @@ module GraphQL
13
13
  def fragments
14
14
  namespace(:fragment_cache)[:fragments] ||= []
15
15
  end
16
+
17
+ def loaded_fragments
18
+ namespace(:fragment_cache)[:loaded] ||= {}
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -49,7 +49,7 @@ module GraphQL
49
49
 
50
50
  cache_fragment_options = @cache_options.merge(object: object_for_key)
51
51
 
52
- object.cache_fragment(cache_fragment_options) do
52
+ object.cache_fragment(**cache_fragment_options) do
53
53
  resolved_value == NOT_RESOLVED ? yield(object, arguments) : resolved_value
54
54
  end
55
55
  end
@@ -4,6 +4,8 @@ require "graphql/fragment_cache/cache_key_builder"
4
4
 
5
5
  module GraphQL
6
6
  module FragmentCache
7
+ using Ext
8
+
7
9
  # Represents a single fragment to cache
8
10
  class Fragment
9
11
  attr_reader :options, :path, :context
@@ -16,10 +18,10 @@ module GraphQL
16
18
 
17
19
  NIL_IN_CACHE = Object.new
18
20
 
19
- def read
20
- FragmentCache.cache_store.read(cache_key).tap do |cached|
21
- return NIL_IN_CACHE if cached.nil? && FragmentCache.cache_store.exist?(cache_key)
22
- end
21
+ def read(keep_in_context = false)
22
+ return read_from_context { value_from_cache } if keep_in_context
23
+
24
+ value_from_cache
23
25
  end
24
26
 
25
27
  def cache_key
@@ -32,6 +34,20 @@ module GraphQL
32
34
 
33
35
  private
34
36
 
37
+ def read_from_context
38
+ if (loaded_value = context.loaded_fragments[cache_key])
39
+ return loaded_value
40
+ end
41
+
42
+ yield.tap { |value| context.loaded_fragments[cache_key] = value }
43
+ end
44
+
45
+ def value_from_cache
46
+ FragmentCache.cache_store.read(cache_key).tap do |cached|
47
+ return NIL_IN_CACHE if cached.nil? && FragmentCache.cache_store.exist?(cache_key)
48
+ end
49
+ end
50
+
35
51
  def interpreter_context
36
52
  context.namespace(:interpreter)
37
53
  end
@@ -27,9 +27,10 @@ module GraphQL
27
27
  context_to_use = context if context_to_use.nil? && respond_to?(:context)
28
28
  raise ArgumentError, "cannot find context, please pass it explicitly" unless context_to_use
29
29
 
30
- fragment = Fragment.new(context_to_use, options)
30
+ fragment = Fragment.new(context_to_use, **options)
31
31
 
32
- if (cached = fragment.read)
32
+ keep_in_context = options.delete(:keep_in_context)
33
+ if (cached = fragment.read(keep_in_context))
33
34
  return cached == Fragment::NIL_IN_CACHE ? nil : raw_value(cached)
34
35
  end
35
36
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module FragmentCache
5
- VERSION = "1.3.0"
5
+ VERSION = "1.4.0"
6
6
  end
7
7
  end
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.3.0
4
+ version: 1.4.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: 2020-11-25 00:00:00.000000000 Z
11
+ date: 2020-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -190,7 +190,7 @@ metadata:
190
190
  homepage_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
191
191
  source_code_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
192
192
  changelog_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/CHANGELOG.md
193
- post_install_message:
193
+ post_install_message:
194
194
  rdoc_options: []
195
195
  require_paths:
196
196
  - lib
@@ -205,8 +205,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
205
  - !ruby/object:Gem::Version
206
206
  version: '0'
207
207
  requirements: []
208
- rubygems_version: 3.0.3
209
- signing_key:
208
+ rubygems_version: 3.1.2
209
+ signing_key:
210
210
  specification_version: 4
211
211
  summary: Fragment cache for graphql-ruby
212
212
  test_files: []