Skip to content

Commit

Permalink
Merge pull request #168 from Shopify/prime
Browse files Browse the repository at this point in the history
Priming the cache
  • Loading branch information
tgwizard authored Feb 23, 2024
2 parents 8e88b28 + 2473813 commit 7aaf3a2
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ def product(id:)
end
```

### Priming the Cache

You can prime the loader cache with a specific value, which can be useful in certain situations.

```ruby
def liked_products
liked_products = Product.where(liked: true).load
liked_products.each do |product|
RecordLoader.for(Product).prime(product.id, product)
end
end
```

Priming will add key/value to the loader cache only if it didn't exist before.


## Unit Testing

Your loaders can be tested outside of a GraphQL query by doing the
Expand Down
4 changes: 4 additions & 0 deletions lib/graphql/batch/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def load_many(keys)
::Promise.all(keys.map { |key| load(key) })
end

def prime(key, value)
cache[cache_key(key)] ||= ::Promise.resolve(value).tap { |p| p.source = self }
end

def resolve #:nodoc:
return if resolved?
load_keys = queue
Expand Down
36 changes: 36 additions & 0 deletions test/loader_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,40 @@ def test_loader_with_failing_perform
promise = ExplodingLoader.load([1]).then(nil, ->(err) { error_message = err.message } ).sync
assert_equal 'perform failed', error_message
end

def test_prime
loader = EchoLoader.for
loader.prime(:a, :prepared_value)

assert_equal :prepared_value, loader.load(:a).sync
assert_equal [:prepared_value, :b, :c], loader.load_many([:a, :b, :c]).sync
end

def test_will_not_call_perform_if_fully_primed
loader = ExplodingLoader.for
loader.prime(:a, 1)
loader.prime(:b, 2)

assert_equal [1, 2], loader.load_many([:a, :b]).sync
end

def test_priming_a_key_already_in_queue_does_nothing
loader = EchoLoader.for

promise = loader.load(:a)

loader.prime(:a, :not_a)

assert_equal :a, promise.sync
end

def test_prime_will_not_replace_already_cached_value
loader = EchoLoader.for

assert_equal :a, loader.load(:a).sync

loader.prime(:a, :not_a)

assert_equal :a, loader.load(:a).sync
end
end

0 comments on commit 7aaf3a2

Please sign in to comment.