Skip to content

Commit 56d9afe

Browse files
Cache result JSON instead of connection objects (#29)
1 parent cb7b8ac commit 56d9afe

File tree

6 files changed

+37
-28
lines changed

6 files changed

+37
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## master
44

5+
- [PR#29](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/29) Cache result JSON instead of connection objects ([@DmitryTsepelev][])
6+
57
## 1.0.2 (2020-08-19)
68

79
- [PR#28](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/28) Support #keys method for GraphQL::FragmentCache::MemoryStore instance ([@reabiliti][])

lib/graphql/fragment_cache.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
require "graphql/fragment_cache/ext/graphql_cache_key"
77
require "graphql/fragment_cache/object"
88

9+
require "graphql/fragment_cache/connections/patch"
10+
911
require "graphql/fragment_cache/schema/patch"
1012
require "graphql/fragment_cache/schema/tracer"
1113
require "graphql/fragment_cache/schema/instrumentation"
@@ -26,6 +28,8 @@ def use(schema_defn, options = {})
2628
schema_defn.tracer(Schema::Tracer)
2729
schema_defn.instrument(:query, Schema::Instrumentation)
2830
schema_defn.extend(Schema::Patch)
31+
32+
GraphQL::Pagination::Connections.prepend(Connections::Patch)
2933
end
3034

3135
def cache_store=(store)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module GraphQL
4+
module FragmentCache
5+
module Connections
6+
# Patches GraphQL::Pagination::Connections to support raw values
7+
module Patch
8+
if Gem::Dependency.new("graphql", ">= 1.11.0").match?("graphql", GraphQL::VERSION)
9+
def wrap(field, parent, items, arguments, context, *options)
10+
raw_value?(items) ? items : super
11+
end
12+
else
13+
def wrap(field, object, arguments, context, *options)
14+
raw_value?(object) ? object : super
15+
end
16+
end
17+
18+
private
19+
20+
def raw_value?(value)
21+
GraphQL::Execution::Interpreter::RawValue === value
22+
end
23+
end
24+
end
25+
end
26+
end

lib/graphql/fragment_cache/fragment.rb

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ module FragmentCache
88
class Fragment
99
attr_reader :options, :path, :context
1010

11-
attr_accessor :resolved_value
12-
1311
def initialize(context, **options)
1412
@context = context
1513
@options = options
@@ -25,9 +23,7 @@ def read
2523
end
2624

2725
def persist
28-
# Connections are not available from the runtime object, so
29-
# we rely on Schema::Tracer to save it for us
30-
value = resolved_value || resolve_from_runtime
26+
value = final_value.dig(*path)
3127
FragmentCache.cache_store.write(cache_key, value, **options)
3228
end
3329

@@ -41,10 +37,6 @@ def interpreter_context
4137
context.namespace(:interpreter)
4238
end
4339

44-
def resolve_from_runtime
45-
final_value.dig(*path)
46-
end
47-
4840
def final_value
4941
@final_value ||= interpreter_context[:runtime].final_value
5042
end

lib/graphql/fragment_cache/object_helpers.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ def cache_fragment(object_to_cache = NO_OBJECT, **options, &block)
2222
fragment = Fragment.new(context, options)
2323

2424
if (cached = fragment.read)
25-
return nil if cached == Fragment::NIL_IN_CACHE
26-
return restore_cached_value(cached)
25+
return cached == Fragment::NIL_IN_CACHE ? nil : raw_value(cached)
2726
end
2827

2928
(block_given? ? block.call : object_to_cache).tap do |resolved_value|
@@ -33,11 +32,6 @@ def cache_fragment(object_to_cache = NO_OBJECT, **options, &block)
3332

3433
private
3534

36-
def restore_cached_value(cached)
37-
# If we return connection object from resolver, Interpreter stops processing it
38-
connection? ? cached : raw_value(cached)
39-
end
40-
4135
def field
4236
interpreter_context[:current_field]
4337
end

lib/graphql/fragment_cache/schema/tracer.rb

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@ class Tracer
1010
class << self
1111
def trace(key, data)
1212
yield.tap do |resolved_value|
13-
next unless connection_to_cache?(key, data)
13+
next unless connection_field?(key, data)
1414

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)
15+
verify_connections!(data[:query].context)
1916
end
2017
end
2118

2219
private
2320

24-
def connection_to_cache?(key, data)
21+
def connection_field?(key, data)
2522
key == "execute_field" && data[:field].connection?
2623
end
2724

@@ -31,12 +28,6 @@ def verify_connections!(context)
3128
raise StandardError,
3229
"GraphQL::Pagination::Connections should be enabled for connection caching"
3330
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
4031
end
4132
end
4233
end

0 commit comments

Comments
 (0)