Class: GraphQL::Language::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/language/cache.rb

Overview

This cache is used by Parser.parse_file when it's enabled.

With Rails, parser caching may enabled by setting config.graphql.parser_cache = true in your Rails application.

The cache may be manually built by assigning GraphQL::Language::Parser.cache = GraphQL::Language::Cache.new(Pathname.new("some_dir"), secret: ENV.fetch("GRAPHQL_CACHE_SECRET")). The secret should be a stable value stored outside of the cache directory. When it isn't provided, a process-local secret is generated and cache entries are rebuilt after the process restarts. Pass secret: nil to disable cache signing. This should only be used when the cache directory is trusted. This will create a directory (tmp/cache/graphql by default) that stores a cache of parsed files.

Much like bootsnap, the parser cache needs to be cleaned up manually. You will need to clear the cache directory for each new deployment of your application. Also note that the parser cache will grow as your schema is loaded, so the cache directory must be writable.

Constant Summary collapse

DIGEST =
Digest::SHA256.new << GraphQL::VERSION
HMAC_SIZE =
OpenSSL::Digest::SHA256.new.digest_length

Instance Method Summary collapse

Constructor Details

#initialize(path, secret: SecureRandom.random_bytes(32)) ⇒ Cache

Returns a new instance of Cache.

Parameters:

  • path (Pathname)

    The directory where cache entries are stored.

  • secret (String, nil) (defaults to: SecureRandom.random_bytes(32))

    A stable secret for verifying cache entries. When omitted, a process-local secret is generated. Pass nil to disable cache signing.



31
32
33
34
# File 'lib/graphql/language/cache.rb', line 31

def initialize(path, secret: SecureRandom.random_bytes(32))
  @path = path
  @secret = secret
end

Instance Method Details

#fetch(filename) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/graphql/language/cache.rb', line 41

def fetch(filename)
  cache_key = cache_key_for(filename)
  return yield unless cache_key

  cache_path = @path.join(cache_key)

  begin
    return load_cache(cache_path, cache_key) if cache_path.file?
  rescue InvalidCache, SystemCallError
    # Rebuild caches created by older versions or with an invalid signature.
  end

  payload = yield
  begin
    write_cache(cache_path, cache_key, payload)
  rescue SystemCallError
    # Parser caching is best-effort; return the parsed payload if the cache cannot be written.
  end
  payload
end