Skip to content
This repository was archived by the owner on Oct 26, 2022. It is now read-only.

Commit f3cfd7c

Browse files
Refactor resolving proc into legit class
1 parent 9b9a0bf commit f3cfd7c

2 files changed

Lines changed: 71 additions & 52 deletions

File tree

lib/graphql/cache/fetcher.rb

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
require 'graphql/cache/resolver'
4+
15
module GraphQL
26
module Cache
37
# Represents the "instrumenter" passed to GraphQL::Schema#instrument
@@ -14,58 +18,7 @@ class Fetcher
1418
def instrument(type, field)
1519
return field unless field.metadata[:cache]
1620

17-
cached_resolve_proc = cached_resolve(type, field)
18-
19-
# Return a copy of `field`, with the new resolve proc
20-
field.redefine { resolve(cached_resolve_proc) }
21-
end
22-
23-
# @private
24-
def cache_key(obj, args, type, field, ctx)
25-
Key.new(obj, args, type, field, ctx).to_s
26-
end
27-
28-
# @private
29-
def cached_resolve(type, field)
30-
old_resolve_proc = field.resolve_proc
31-
32-
lambda do |obj, args, ctx|
33-
key = cache_key(obj, args, type, field, ctx)
34-
35-
value = Marshal[key].read(
36-
field.metadata[:cache], force: ctx[:force_cache]
37-
) do
38-
old_resolve_proc.call(obj, args, ctx)
39-
end
40-
41-
wrap_connections(value, args, field: field, parent: obj, context: ctx)
42-
end
43-
end
44-
45-
# @private
46-
def wrap_connections(value, args, **kwargs)
47-
# return raw value if field isn't a connection (no need to wrap)
48-
return value unless kwargs[:field].connection?
49-
50-
# return cached value if it is already a connection object
51-
# this occurs when the value is being resolved by GraphQL
52-
# and not being read from cache
53-
return value if value.class.ancestors.include?(
54-
GraphQL::Relay::BaseConnection
55-
)
56-
57-
create_connection(value, args, **kwargs)
58-
end
59-
60-
# @private
61-
def create_connection(value, args, **kwargs)
62-
GraphQL::Relay::BaseConnection.connection_for_nodes(value).new(
63-
value,
64-
args,
65-
field: kwargs[:field],
66-
parent: kwargs[:parent],
67-
context: kwargs[:context]
68-
)
21+
field.redefine { resolve(GraphQL::Cache::Resolver.new(type, field)) }
6922
end
7023
end
7124
end

lib/graphql/cache/resolver.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# frozen_string_literal: true
2+
3+
module GraphQL
4+
module Cache
5+
# Represents the caching resolver that wraps the existing resolver proc
6+
class Resolver
7+
attr_accessor :type
8+
9+
attr_accessor :field
10+
11+
attr_accessor :orig_resolve_proc
12+
13+
def initialize(type, field)
14+
@type = type
15+
@field = field
16+
end
17+
18+
def call(obj, args, ctx)
19+
@orig_resolve_proc = field.resolve_proc
20+
21+
key = cache_key(obj, args, ctx)
22+
23+
value = Marshal[key].read(
24+
field.metadata[:cache], force: ctx[:force_cache]
25+
) do
26+
@orig_resolve_proc.call(obj, args, ctx)
27+
end
28+
29+
wrap_connections(value, args, parent: obj, context: ctx)
30+
end
31+
32+
protected
33+
34+
# @private
35+
def cache_key(obj, args, ctx)
36+
Key.new(obj, args, type, field, ctx).to_s
37+
end
38+
39+
# @private
40+
def wrap_connections(value, args, **kwargs)
41+
# return raw value if field isn't a connection (no need to wrap)
42+
return value unless field.connection?
43+
44+
# return cached value if it is already a connection object
45+
# this occurs when the value is being resolved by GraphQL
46+
# and not being read from cache
47+
return value if value.class.ancestors.include?(
48+
GraphQL::Relay::BaseConnection
49+
)
50+
51+
create_connection(value, args, **kwargs)
52+
end
53+
54+
# @private
55+
def create_connection(value, args, **kwargs)
56+
GraphQL::Relay::BaseConnection.connection_for_nodes(value).new(
57+
value,
58+
args,
59+
field: field,
60+
parent: kwargs[:parent],
61+
context: kwargs[:context]
62+
)
63+
end
64+
end
65+
end
66+
end

0 commit comments

Comments
 (0)