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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb2192273e278a5586abc0e640ef6057f28e072f38b46740a5e0ebf6364f7be1
4
- data.tar.gz: 59d4fd50a85cbc58a6109373f4fb4dca69aa54548960e7be62af5cb98b4cf6cd
3
+ metadata.gz: 90827abbbae2111c06ea2a0afc7f9daea103098064949eba4bbd84cd791c2fdb
4
+ data.tar.gz: 2efebce54277a3fef786d189b9c9bcb9a46dfa22c412a9b51f29f6652e3031c6
5
5
  SHA512:
6
- metadata.gz: 06c5fe310bf069f2017be61070b3eb809edf006473ef0f4c3e9eb27fda37278cb683a95cffceef3bd74fade59a9b76560bb7234bdfc09adc788b734667ebd110
7
- data.tar.gz: dd2f2eed8a84be514eb760a98c62040f2854cc1d98c6ccb4790fe314d50b0ea75015b1ef0600e0239b080701619b0ed5496b6f305847855f2fadfa91adf4c943
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.2.5)
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.4)
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.2
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 middleware for [graphql-ruby](https://github.com/rmosolgo/graphql-ruby)
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
- When passing a hash in the `cache` parameter the possible options are:
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
- - `expiry`: expiration time for this field's key in seconds (default: 5400)
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
- old_resolve_proc = field.resolve_proc
5
+ return field unless field.metadata[:cache]
6
6
 
7
- new_resolve_proc = lambda do |obj, args, ctx|
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(new_resolve_proc) }
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?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module Cache
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
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.3.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-07-27 00:00:00.000000000 Z
11
+ date: 2018-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal