graphql-cache 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +21 -5
- data/lib/graphql/cache.rb +0 -5
- data/lib/graphql/cache/fetcher.rb +16 -13
- data/lib/graphql/cache/marshal.rb +4 -1
- data/lib/graphql/cache/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90827abbbae2111c06ea2a0afc7f9daea103098064949eba4bbd84cd791c2fdb
|
4
|
+
data.tar.gz: 2efebce54277a3fef786d189b9c9bcb9a46dfa22c412a9b51f29f6652e3031c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d85a82ed4c3dae977475ad723fd6a2c61c676f3e887db196ef1aaa5100c81c2a54a5fc3874ae427baa023a2d00b8e9446a16536cef656c7c7c623b670118032a
|
7
|
+
data.tar.gz: b0abbd392cc526d552dc5a1296187f053e1a1d66d6f7127eb779602bdbb74b9dec6848308e6d6d94bb199ef94a8b4071def6126a262d6e90b8c8048a3a124a67
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
graphql-cache (0.
|
4
|
+
graphql-cache (0.4.0)
|
5
5
|
graphql (~> 1.8.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -16,7 +16,7 @@ GEM
|
|
16
16
|
coderay (1.1.2)
|
17
17
|
diff-lcs (1.3)
|
18
18
|
docile (1.3.0)
|
19
|
-
graphql (1.8.
|
19
|
+
graphql (1.8.6)
|
20
20
|
json (2.1.0)
|
21
21
|
method_source (0.9.0)
|
22
22
|
mini_cache (1.1.0)
|
@@ -63,4 +63,4 @@ DEPENDENCIES
|
|
63
63
|
sqlite3
|
64
64
|
|
65
65
|
BUNDLED WITH
|
66
|
-
1.16.
|
66
|
+
1.16.3
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# GraphQL Cache
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/graphql-cache.svg)](https://badge.fury.io/rb/graphql-cache) [![Build Status](https://travis-ci.org/stackshareio/graphql-cache.svg?branch=master)](https://travis-ci.org/stackshareio/graphql-cache) [![Test Coverage](https://api.codeclimate.com/v1/badges/524c0f23ed1dbf0f9338/test_coverage)](https://codeclimate.com/github/stackshareio/graphql-cache/test_coverage) [![Maintainability](https://api.codeclimate.com/v1/badges/524c0f23ed1dbf0f9338/maintainability)](https://codeclimate.com/github/stackshareio/graphql-cache/maintainability)
|
5
5
|
|
6
|
-
A custom
|
6
|
+
A custom caching plugin for [graphql-ruby](https://github.com/rmosolgo/graphql-ruby)
|
7
7
|
|
8
8
|
## Goals
|
9
9
|
|
@@ -79,17 +79,33 @@ Any object, list, or connection field can be cached by simply adding `cache: tru
|
|
79
79
|
field :calculated_field, Int, cache: true
|
80
80
|
```
|
81
81
|
|
82
|
+
### Custom Expirations
|
83
|
+
|
82
84
|
By default all keys will have an expiration of `GraphQL::Cache.expiry` which defaults to 90 minutes. If you want to set a field-specific expiration time pass a hash to the `cache` parameter like this:
|
83
85
|
|
84
86
|
```ruby
|
85
87
|
field :calculated_field, Int, cache: { expiry: 10800 } # expires key after 180 minutes
|
86
88
|
```
|
87
89
|
|
88
|
-
|
90
|
+
### Custom cache keys
|
91
|
+
|
92
|
+
GraphQL Cache generates a cache key using the context of a query during execution. A custom key can be included to implement versioned caching as well. By providing a `:key` value to the cache config hash on a field definition. For example, to use a custom method that returns the cache key for an object use:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
field :calculated_field, Int, cache: { key: :custom_cache_key }
|
96
|
+
```
|
97
|
+
|
98
|
+
With this configuration the cache key used for this resolved value will use the result of the method `custom_cache_key` called on the parent object.
|
99
|
+
|
100
|
+
### Forcing the cache
|
101
|
+
|
102
|
+
It is possible to force graphql-cache to resolve and write all cached fields to cache regardless of the presence of a given key in the cache store. This will effectively "renew" any existing cached expirations and warm any that don't exist. To use forced caching, add a value to `:force_cache` in the query context:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
MySchema.execute('{ company(id: 123) { cachedField }}', context: { force_cache: true })
|
106
|
+
```
|
89
107
|
|
90
|
-
|
91
|
-
- `force`: for cache misses on this field (default: false)
|
92
|
-
- `prefix`: cache key prefix (appended after GraphQL::Cache.namespace)
|
108
|
+
This will resolve all cached fields using the field's resolver and write them to cache without first reading the value at their respective cache keys. This is useful for structured cache warming strategies where the cache expiration needs to be updated when a warming query is made.
|
93
109
|
|
94
110
|
## Development
|
95
111
|
|
data/lib/graphql/cache.rb
CHANGED
@@ -17,10 +17,6 @@ module GraphQL
|
|
17
17
|
# @return [Integer] Default: 5400 (90 minutes)
|
18
18
|
attr_accessor :expiry
|
19
19
|
|
20
|
-
# When truthy, override all caching (force evalutaion of resolvers)
|
21
|
-
# @return [Boolean] Default: false
|
22
|
-
attr_accessor :force
|
23
|
-
|
24
20
|
# Logger instance to use when logging cache hits/misses.
|
25
21
|
# @return [Logger]
|
26
22
|
attr_accessor :logger
|
@@ -43,7 +39,6 @@ module GraphQL
|
|
43
39
|
|
44
40
|
# Default configuration
|
45
41
|
@expiry = 5400
|
46
|
-
@force = false
|
47
42
|
@namespace = 'graphql'
|
48
43
|
|
49
44
|
# Called by plugin framework in graphql-ruby to
|
@@ -2,28 +2,31 @@ module GraphQL
|
|
2
2
|
module Cache
|
3
3
|
class Fetcher
|
4
4
|
def instrument(type, field)
|
5
|
-
|
5
|
+
return field unless field.metadata[:cache]
|
6
6
|
|
7
|
-
|
8
|
-
unless field.metadata[:cache]
|
9
|
-
return old_resolve_proc.call(obj, args, ctx)
|
10
|
-
end
|
11
|
-
|
12
|
-
key = cache_key(obj, args, type, field)
|
13
|
-
|
14
|
-
Marshal[key].read(field.metadata[:cache]) do
|
15
|
-
old_resolve_proc.call(obj, args, ctx)
|
16
|
-
end
|
17
|
-
end
|
7
|
+
cached_resolve_proc = cached_resolve(type, field)
|
18
8
|
|
19
9
|
# Return a copy of `field`, with the new resolve proc
|
20
|
-
field.redefine { resolve(
|
10
|
+
field.redefine { resolve(cached_resolve_proc) }
|
21
11
|
end
|
22
12
|
|
23
13
|
# @private
|
24
14
|
def cache_key(obj, args, type, field)
|
25
15
|
Key.new(obj, args, type, field).to_s
|
26
16
|
end
|
17
|
+
|
18
|
+
# @private
|
19
|
+
def cached_resolve(type, field)
|
20
|
+
old_resolve_proc = field.resolve_proc
|
21
|
+
|
22
|
+
lambda do |obj, args, ctx|
|
23
|
+
key = cache_key(obj, args, type, field)
|
24
|
+
|
25
|
+
Marshal[key].read(field.metadata[:cache], force: ctx[:force_cache]) do
|
26
|
+
old_resolve_proc.call(obj, args, ctx)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
@@ -29,7 +29,10 @@ module GraphQL
|
|
29
29
|
#
|
30
30
|
# @param config [Hash] The object passed to `cache:` on the field definition
|
31
31
|
# @return [Object]
|
32
|
-
def read(config, &block)
|
32
|
+
def read(config, force: false, &block)
|
33
|
+
# write new data from resolver if forced
|
34
|
+
return write(config, &block) if force
|
35
|
+
|
33
36
|
cached = cache.read(key)
|
34
37
|
|
35
38
|
if cached.nil?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Kelly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|