graphql-fragment_cache 0.1.6 → 0.1.7
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/graphql/fragment_cache.rb +7 -5
- data/lib/graphql/fragment_cache/cacher.rb +1 -3
- data/lib/graphql/fragment_cache/fragment.rb +16 -6
- data/lib/graphql/fragment_cache/object_helpers.rb +3 -38
- data/lib/graphql/fragment_cache/schema/instrumentation.rb +23 -0
- data/lib/graphql/fragment_cache/schema/patch.rb +16 -0
- data/lib/graphql/fragment_cache/schema/tracer.rb +44 -0
- data/lib/graphql/fragment_cache/version.rb +1 -1
- metadata +5 -5
- data/lib/.rbnext/2.7/graphql/fragment_cache/cacher.rb +0 -20
- data/lib/graphql/fragment_cache/instrumentation.rb +0 -21
- data/lib/graphql/fragment_cache/schema_patch.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c1bfd3dbaadd053ae1e47ac16d1cb244410adeae3424b30d58b04516447bfe6
|
4
|
+
data.tar.gz: 10de0c52b16423e65db745433a61aef94c795edca3b4b47c3ef834f7118d0a5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54ad113a7ef913df0c283c130bae045621dd99298bb1e658e6a4e00440fa29a6ac3d39f45789b49f9cc8a09ddaf34fe4af18560ebbc1c41d73e33d6e539e9b10
|
7
|
+
data.tar.gz: b36091bf683d1018e47ae0fcfd5e69fedad20d4a7b20687a67315d721efa63a5b5df158cb8142ed6342b5ae77c3bd41d08a281299d16f0fcd10d74107e5db78e
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
|
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.
|
26
|
-
schema_defn.
|
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
|
-
|
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
|
9
|
+
attr_reader :options, :path, :context
|
10
10
|
|
11
|
-
|
11
|
+
attr_accessor :resolved_value
|
12
12
|
|
13
13
|
def initialize(context, **options)
|
14
14
|
@context = context
|
15
15
|
@options = options
|
16
|
-
@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
|
24
|
-
|
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
|
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
|
-
|
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
|
39
|
-
|
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
|
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.
|
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-
|
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/
|
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
|