Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expose cacheKeyFn #76

Closed
Janpot opened this issue Mar 27, 2017 · 6 comments
Closed

expose cacheKeyFn #76

Janpot opened this issue Mar 27, 2017 · 6 comments

Comments

@Janpot
Copy link

Janpot commented Mar 27, 2017

Working on a pattern where I wrap one dataloader with another. It would be useful to have the cacheKeyFn exposed on the dataloader instance so I can use it for inner cache key generation and pass it through to inner dataloaders.

Example:

var client = redis.createClient();

function wrapWithCache (dataloader) {
  const redisLoader = new DataLoader(keys => new Promise((resolve, reject) => {
    // here to generate redis keys:
    const redisKeys = keys.map(dataloader.cacheKeyFn);
    client.mget(redisKeys, (error, results) => {
      if (error) {
        return reject(error);
      }
      resolve(results.map((result, index) =>
        result !== null ? result : new Error(`No key: ${keys[index]}`)
      ));
    });
  // here for the redisLoader cache:
  }), { cacheKeyFn: dataloader.cacheKeyFn });

  return new DataLoader(keys => {
    return Promise.all(keys.map(key => {
      return redisLoader.load(key).catch(() => dataloader.load(key));
    }));
  // here for the wrapping dataloader cache:
  }, { cacheKeyFn: dataloader.cacheKeyFn });
}

I now do

const { cacheKeyFn = x => x } = dataloader._options || {};

but I prefer a public getter

@leebyron
Copy link
Contributor

Interesting idea

@caub
Copy link
Contributor

caub commented Mar 18, 2018

@Janpot Why don't you define and pass a cacheKeyFn and/or cacheMap, that you can manipulate from both dataloaders?

@Janpot
Copy link
Author

Janpot commented Mar 18, 2018

@caub I'm not sure I understand. My pattern is wrapping a dataloader, that might be obtained from anywhere, whose creation you might not be in control of. Could you show some pseudocode to illustrate your pattern?

@caub
Copy link
Contributor

caub commented Mar 18, 2018

@Janpot ah I see, ideally you should have the cache along the wrapper loader function wrapWithCache(dataloader, cache) { .. }. As soon as you have the cache, and share it between 2 dataloaders, it'll use it, you can even insert manually promises in it: https://runkit.com/caub/5aae792008932d00128c1523

@Janpot
Copy link
Author

Janpot commented Apr 12, 2018

@caub So this philosophy has changed? #24
I'm trying to make sense of it

@leebyron
Copy link
Contributor

I'm going to close this aging issue. Looking back on this, this makes an assumption that a local cache key mapping function is recyclable as a redis key function, and while that may be true for this particular app, it's probably not generally useful to warrant expanding the public API.

Otherwise, I don't see a huge problem with touching private API if it works for you and you're not afraid of checking behavioral changes when upgrading (write tests!)

However note that to support the next release your code will need to adjust because of #226. The change should make your code closer to what you originally hoped to write.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants