graphql-fragment_cache 0.1.6 → 0.1.7

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: d83b3ff9d3e9cc91b6f013214d2cc4d97c6d2fc8bd377bf38d1f68dd7f935c23
4
- data.tar.gz: d349157e8c6856c06b5a3ae76915399ae77fc04153093ef9551bb75b45629cb4
3
+ metadata.gz: 1c1bfd3dbaadd053ae1e47ac16d1cb244410adeae3424b30d58b04516447bfe6
4
+ data.tar.gz: 10de0c52b16423e65db745433a61aef94c795edca3b4b47c3ef834f7118d0a5f
5
5
  SHA512:
6
- metadata.gz: 759813c8b9ae4373d9890519aa88573eb9a504771eca25ea7d7ddc2a35b972f172e1fb7e86bbd2f52447886e3c781178cfc7491c9a7257ce436ae411a32395fb
7
- data.tar.gz: 78c75d761fc3154dd4a4622a36c5b0f7bbc4b26c31eb4bf3e3c6be4423be8ae64923d7207f02217142c213fa80e039410e2d079403c0258efd82543d9866e41d
6
+ metadata.gz: 54ad113a7ef913df0c283c130bae045621dd99298bb1e658e6a4e00440fa29a6ac3d39f45789b49f9cc8a09ddaf34fe4af18560ebbc1c41d73e33d6e539e9b10
7
+ data.tar.gz: b36091bf683d1018e47ae0fcfd5e69fedad20d4a7b20687a67315d721efa63a5b5df158cb8142ed6342b5ae77c3bd41d08a281299d16f0fcd10d74107e5db78e
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.1.7 (2020-06-02)
6
+
7
+ - [PR#23](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/23) Avoid extra queries after restoring connection from cache ([@DmitryTsepelev][])
8
+
5
9
  ## 0.1.6 (2020-05-30)
6
10
 
7
11
  - [PR#22](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/22) Properly cache entites inside collections ([@DmitryTsepelev][])
@@ -4,10 +4,11 @@ require "graphql"
4
4
 
5
5
  require "graphql/fragment_cache/ext/context_fragments"
6
6
  require "graphql/fragment_cache/ext/graphql_cache_key"
7
-
8
- require "graphql/fragment_cache/schema_patch"
9
7
  require "graphql/fragment_cache/object"
10
- require "graphql/fragment_cache/instrumentation"
8
+
9
+ require "graphql/fragment_cache/schema/patch"
10
+ require "graphql/fragment_cache/schema/tracer"
11
+ require "graphql/fragment_cache/schema/instrumentation"
11
12
 
12
13
  require "graphql/fragment_cache/memory_store"
13
14
 
@@ -22,8 +23,9 @@ module GraphQL
22
23
  def use(schema_defn, options = {})
23
24
  verify_interpreter!(schema_defn)
24
25
 
25
- schema_defn.instrument(:query, Instrumentation)
26
- schema_defn.extend(SchemaPatch)
26
+ schema_defn.tracer(Schema::Tracer)
27
+ schema_defn.instrument(:query, Schema::Instrumentation)
28
+ schema_defn.extend(Schema::Patch)
27
29
  end
28
30
 
29
31
  def cache_store=(store)
@@ -10,9 +10,7 @@ module GraphQL
10
10
  def call(query)
11
11
  return unless query.context.fragments?
12
12
 
13
- final_value = query.context.namespace(:interpreter)[:runtime].final_value
14
-
15
- query.context.fragments.each { _1.persist(final_value) }
13
+ query.context.fragments.each(&:persist)
16
14
  end
17
15
  end
18
16
  end
@@ -6,22 +6,24 @@ module GraphQL
6
6
  module FragmentCache
7
7
  # Represents a single fragment to cache
8
8
  class Fragment
9
- attr_reader :options, :path, :context, :raw_connection
9
+ attr_reader :options, :path, :context
10
10
 
11
- attr_writer :raw_connection
11
+ attr_accessor :resolved_value
12
12
 
13
13
  def initialize(context, **options)
14
14
  @context = context
15
15
  @options = options
16
- @path = context.namespace(:interpreter)[:current_path]
16
+ @path = interpreter_context[:current_path]
17
17
  end
18
18
 
19
19
  def read
20
20
  FragmentCache.cache_store.read(cache_key)
21
21
  end
22
22
 
23
- def persist(final_value)
24
- value = raw_connection || resolve(final_value)
23
+ def persist
24
+ # Connections are not available from the runtime object, so
25
+ # we rely on Schema::Tracer to save it for us
26
+ value = resolved_value || resolve_from_runtime
25
27
  FragmentCache.cache_store.write(cache_key, value, **options)
26
28
  end
27
29
 
@@ -31,9 +33,17 @@ module GraphQL
31
33
  @cache_key ||= CacheKeyBuilder.call(path: path, query: context.query, **options)
32
34
  end
33
35
 
34
- def resolve(final_value)
36
+ def interpreter_context
37
+ context.namespace(:interpreter)
38
+ end
39
+
40
+ def resolve_from_runtime
35
41
  final_value.dig(*path)
36
42
  end
43
+
44
+ def final_value
45
+ @final_value ||= interpreter_context[:runtime].final_value
46
+ end
37
47
  end
38
48
  end
39
49
  end
@@ -6,8 +6,6 @@ module GraphQL
6
6
  module FragmentCache
7
7
  using Ext
8
8
 
9
- RawConnection = Struct.new(:items, :nodes, :paged_nodes_offset, :has_previous_page, :has_next_page)
10
-
11
9
  # Adds #cache_fragment method
12
10
  module ObjectHelpers
13
11
  extend Forwardable
@@ -28,35 +26,15 @@ module GraphQL
28
26
  end
29
27
 
30
28
  (block_given? ? block.call : object_to_cache).tap do |resolved_value|
31
- cache_value(resolved_value, fragment)
29
+ context.fragments << fragment
32
30
  end
33
31
  end
34
32
 
35
33
  private
36
34
 
37
35
  def restore_cached_value(cached)
38
- connection? ? restore_cached_connection(cached) : raw_value(cached)
39
- end
40
-
41
- def cache_value(resolved_value, fragment)
42
- if connection?
43
- unless context.schema.new_connections?
44
- raise StandardError,
45
- "GraphQL::Pagination::Connections should be enabled for connection caching"
46
- end
47
-
48
- connection = wrap_connection(resolved_value)
49
-
50
- fragment.raw_connection = RawConnection.new(
51
- connection.items,
52
- connection.nodes,
53
- connection.instance_variable_get(:@paged_nodes_offset),
54
- connection.has_previous_page,
55
- connection.has_next_page
56
- )
57
- end
58
-
59
- context.fragments << fragment
36
+ # If we return connection object from resolver, Interpreter stops processing it
37
+ connection? ? cached : raw_value(cached)
60
38
  end
61
39
 
62
40
  def field
@@ -66,19 +44,6 @@ module GraphQL
66
44
  def interpreter_context
67
45
  @interpreter_context ||= context.namespace(:interpreter)
68
46
  end
69
-
70
- def restore_cached_connection(raw_connection)
71
- wrap_connection(raw_connection.items).tap do |connection|
72
- connection.instance_variable_set(:@nodes, raw_connection.nodes)
73
- connection.instance_variable_set(:@paged_nodes_offset, raw_connection.paged_nodes_offset)
74
- connection.instance_variable_set(:@has_previous_page, raw_connection.has_previous_page)
75
- connection.instance_variable_set(:@has_next_page, raw_connection.has_next_page)
76
- end
77
- end
78
-
79
- def wrap_connection(object)
80
- context.schema.connections.wrap(field, object, interpreter_context[:current_arguments], context)
81
- end
82
47
  end
83
48
  end
84
49
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/fragment_cache/cacher"
4
+
5
+ module GraphQL
6
+ module FragmentCache
7
+ module Schema
8
+ # Adds hook for saving cached values after query is resolved
9
+ module Instrumentation
10
+ module_function
11
+
12
+ def before_query(query)
13
+ end
14
+
15
+ def after_query(query)
16
+ return unless query.valid?
17
+
18
+ Cacher.call(query)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/sha1"
4
+
5
+ module GraphQL
6
+ module FragmentCache
7
+ module Schema
8
+ # Patches GraphQL::Schema to support fragment cache
9
+ module Patch
10
+ def schema_cache_key
11
+ @schema_cache_key ||= Digest::SHA1.hexdigest(to_definition)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ # Plugin definition
5
+ module FragmentCache
6
+ module Schema
7
+ class Tracer
8
+ using Ext
9
+
10
+ class << self
11
+ def trace(key, data)
12
+ yield.tap do |resolved_value|
13
+ next unless connection_to_cache?(key, data)
14
+
15
+ # We need to attach connection object to fragment and save it later
16
+ context = data[:query].context
17
+ verify_connections!(context)
18
+ cache_connection(resolved_value, context)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def connection_to_cache?(key, data)
25
+ key == "execute_field" && data[:field].connection?
26
+ end
27
+
28
+ def verify_connections!(context)
29
+ return if context.schema.new_connections?
30
+
31
+ raise StandardError,
32
+ "GraphQL::Pagination::Connections should be enabled for connection caching"
33
+ end
34
+
35
+ def cache_connection(resolved_value, context)
36
+ current_path = context.namespace(:interpreter)[:current_path]
37
+ fragment = context.fragments.find { |fragment| fragment.path == current_path }
38
+ fragment.resolved_value = resolved_value if fragment
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module FragmentCache
5
- VERSION = "0.1.6"
5
+ VERSION = "0.1.7"
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: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-30 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -149,7 +149,6 @@ files:
149
149
  - bin/console
150
150
  - bin/setup
151
151
  - lib/.rbnext/2.7/graphql/fragment_cache/cache_key_builder.rb
152
- - lib/.rbnext/2.7/graphql/fragment_cache/cacher.rb
153
152
  - lib/.rbnext/2.7/graphql/fragment_cache/ext/graphql_cache_key.rb
154
153
  - lib/graphql-fragment_cache.rb
155
154
  - lib/graphql/fragment_cache.rb
@@ -159,13 +158,14 @@ files:
159
158
  - lib/graphql/fragment_cache/ext/graphql_cache_key.rb
160
159
  - lib/graphql/fragment_cache/field_extension.rb
161
160
  - lib/graphql/fragment_cache/fragment.rb
162
- - lib/graphql/fragment_cache/instrumentation.rb
163
161
  - lib/graphql/fragment_cache/memory_store.rb
164
162
  - lib/graphql/fragment_cache/object.rb
165
163
  - lib/graphql/fragment_cache/object_helpers.rb
166
164
  - lib/graphql/fragment_cache/rails/cache_key_builder.rb
167
165
  - lib/graphql/fragment_cache/railtie.rb
168
- - lib/graphql/fragment_cache/schema_patch.rb
166
+ - lib/graphql/fragment_cache/schema/instrumentation.rb
167
+ - lib/graphql/fragment_cache/schema/patch.rb
168
+ - lib/graphql/fragment_cache/schema/tracer.rb
169
169
  - lib/graphql/fragment_cache/version.rb
170
170
  homepage: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
171
171
  licenses:
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- module FragmentCache
5
- using Ext
6
-
7
- # Saves resolved fragment values to cache store
8
- module Cacher
9
- class << self
10
- def call(query)
11
- return unless query.context.fragments?
12
-
13
- final_value = query.context.namespace(:interpreter)[:runtime].final_value
14
-
15
- query.context.fragments.each { |_1| _1.persist(final_value) }
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "graphql/fragment_cache/cacher"
4
-
5
- module GraphQL
6
- module FragmentCache
7
- # Adds hook for saving cached values after query is resolved
8
- module Instrumentation
9
- module_function
10
-
11
- def before_query(query)
12
- end
13
-
14
- def after_query(query)
15
- return unless query.valid?
16
-
17
- Cacher.call(query)
18
- end
19
- end
20
- end
21
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "digest/sha1"
4
-
5
- module GraphQL
6
- module FragmentCache
7
- # Patches GraphQL::Schema to support fragment cache
8
- module SchemaPatch
9
- def schema_cache_key
10
- @schema_cache_key ||= Digest::SHA1.hexdigest(to_definition)
11
- end
12
- end
13
- end
14
- end