@expo/entity-cache-adapter-redis 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/build/GenericRedisCacher.d.ts +10 -2
  2. package/build/GenericRedisCacher.js.map +1 -1
  3. package/build/RedisCacheAdapter.d.ts +2 -2
  4. package/build/RedisCacheAdapter.js.map +1 -1
  5. package/build/__integration-tests__/BatchedRedisCacheAdapter-integration-test.d.ts +1 -0
  6. package/build/__integration-tests__/BatchedRedisCacheAdapter-integration-test.js +124 -0
  7. package/build/__integration-tests__/BatchedRedisCacheAdapter-integration-test.js.map +1 -0
  8. package/build/__integration-tests__/GenericRedisCacher-integration-test.js +5 -4
  9. package/build/__integration-tests__/GenericRedisCacher-integration-test.js.map +1 -1
  10. package/build/__integration-tests__/RedisCacheAdapter-integration-test.js +7 -6
  11. package/build/__integration-tests__/RedisCacheAdapter-integration-test.js.map +1 -1
  12. package/build/__integration-tests__/errors-test.js +4 -3
  13. package/build/__integration-tests__/errors-test.js.map +1 -1
  14. package/build/testfixtures/createRedisIntegrationTestEntityCompanionProvider.js +3 -1
  15. package/build/testfixtures/createRedisIntegrationTestEntityCompanionProvider.js.map +1 -1
  16. package/package.json +3 -3
  17. package/src/GenericRedisCacher.ts +12 -2
  18. package/src/RedisCacheAdapter.ts +2 -3
  19. package/src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts +164 -0
  20. package/src/__integration-tests__/GenericRedisCacher-integration-test.ts +5 -4
  21. package/src/__integration-tests__/RedisCacheAdapter-integration-test.ts +7 -12
  22. package/src/__integration-tests__/errors-test.ts +4 -3
  23. package/src/testfixtures/createRedisIntegrationTestEntityCompanionProvider.ts +4 -1
@@ -1,10 +1,18 @@
1
1
  import { CacheLoadResult, EntityConfiguration, IEntityGenericCacher } from '@expo/entity';
2
- import { Redis } from 'ioredis';
2
+ export interface IRedisTransaction {
3
+ set(key: string, value: string, secondsToken: 'EX', seconds: number): this;
4
+ exec(): Promise<any>;
5
+ }
6
+ export interface IRedis {
7
+ mget(...args: [...keys: string[]]): Promise<(string | null)[]>;
8
+ multi(): IRedisTransaction;
9
+ del(...args: [...keys: string[]]): Promise<any>;
10
+ }
3
11
  export interface GenericRedisCacheContext {
4
12
  /**
5
13
  * Instance of ioredis.Redis
6
14
  */
7
- redisClient: Redis;
15
+ redisClient: IRedis;
8
16
  /**
9
17
  * TTL for caching database hits. Successive entity loads within this TTL
10
18
  * will be read from cache (unless invalidated).
@@ -1 +1 @@
1
- {"version":3,"file":"GenericRedisCacher.js","sourceRoot":"","sources":["../src/GenericRedisCacher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GenericRedisCacher.js","sourceRoot":"","sources":["../src/GenericRedisCacher.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { EntityCacheAdapter, EntityConfiguration, CacheLoadResult } from '@expo/entity';
2
- import type { Redis } from 'ioredis';
2
+ import { IRedis } from './GenericRedisCacher';
3
3
  export interface RedisCacheAdapterContext {
4
4
  /**
5
5
  * Instance of ioredis.Redis
6
6
  */
7
- redisClient: Redis;
7
+ redisClient: IRedis;
8
8
  /**
9
9
  * Create a key string for key parts (cache key prefix, versions, entity name, etc).
10
10
  * Most commonly a simple `parts.join(':')`. See integration test for example.
@@ -1 +1 @@
1
- {"version":3,"file":"RedisCacheAdapter.js","sourceRoot":"","sources":["../src/RedisCacheAdapter.ts"],"names":[],"mappings":";;;;;AAAA,yCAAiG;AACjG,0DAAkC;AAGlC,8EAAsD;AAuCtD,MAAqB,iBAA2B,SAAQ,2BAA2B;IAEjF,YACE,mBAAiD,EAChC,OAAiC;QAElD,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAFV,YAAO,GAAP,OAAO,CAA0B;QAIlD,IAAI,CAAC,kBAAkB,GAAG,IAAI,4BAAkB,CAC9C;YACE,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;SAC/C,EACD,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,aAAa,CACxB,SAAY,EACZ,WAA+C;QAE/C,MAAM,gCAAgC,GAAG,IAAI,GAAG,CAC9C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC,CACxF,CAAC;QACF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAC9D,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,IAAI,EAAE,CAAC,CACpD,CAAC;QAEF,OAAO,IAAA,gBAAO,EAAC,YAAY,EAAE,CAAC,aAAa,EAAE,EAAE;YAC7C,MAAM,UAAU,GAAG,gCAAgC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACvE,IAAA,mBAAS,EACP,UAAU,KAAK,SAAS,EACxB,6DAA6D,EAC7D,aAAa,CACd,CAAC;YACF,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,SAAY,EACZ,SAAkE;QAElE,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAC1C,IAAA,gBAAO,EAAC,SAAS,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC7E,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAC7B,SAAY,EACZ,WAA+C;QAE/C,MAAM,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAC9C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC9B,SAAY,EACZ,WAA+C;QAE/C,MAAM,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAC/C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC;IAEO,YAAY,CAClB,SAAY,EACZ,UAAmC;QAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtF,IAAA,mBAAS,EAAC,UAAU,EAAE,sCAAsC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAC3B,IAAI,CAAC,OAAO,CAAC,cAAc,EAC3B,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAClC,MAAM,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,EAChD,UAAU,EACV,MAAM,CAAC,UAAU,CAAC,CACnB,CAAC;IACJ,CAAC;CACF;AAjFD,oCAiFC"}
1
+ {"version":3,"file":"RedisCacheAdapter.js","sourceRoot":"","sources":["../src/RedisCacheAdapter.ts"],"names":[],"mappings":";;;;;AAAA,yCAAiG;AACjG,0DAAkC;AAElC,8EAAkE;AAuClE,MAAqB,iBAA2B,SAAQ,2BAA2B;IAEjF,YACE,mBAAiD,EAChC,OAAiC;QAElD,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAFV,YAAO,GAAP,OAAO,CAA0B;QAIlD,IAAI,CAAC,kBAAkB,GAAG,IAAI,4BAAkB,CAC9C;YACE,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;SAC/C,EACD,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,aAAa,CACxB,SAAY,EACZ,WAA+C;QAE/C,MAAM,gCAAgC,GAAG,IAAI,GAAG,CAC9C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC,CACxF,CAAC;QACF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAC9D,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,IAAI,EAAE,CAAC,CACpD,CAAC;QAEF,OAAO,IAAA,gBAAO,EAAC,YAAY,EAAE,CAAC,aAAa,EAAE,EAAE;YAC7C,MAAM,UAAU,GAAG,gCAAgC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACvE,IAAA,mBAAS,EACP,UAAU,KAAK,SAAS,EACxB,6DAA6D,EAC7D,aAAa,CACd,CAAC;YACF,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,SAAY,EACZ,SAAkE;QAElE,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAC1C,IAAA,gBAAO,EAAC,SAAS,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC7E,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAC7B,SAAY,EACZ,WAA+C;QAE/C,MAAM,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAC9C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC9B,SAAY,EACZ,WAA+C;QAE/C,MAAM,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAC/C,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC;IAEO,YAAY,CAClB,SAAY,EACZ,UAAmC;QAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtF,IAAA,mBAAS,EAAC,UAAU,EAAE,sCAAsC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAC3B,IAAI,CAAC,OAAO,CAAC,cAAc,EAC3B,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAClC,MAAM,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,EAChD,UAAU,EACV,MAAM,CAAC,UAAU,CAAC,CACnB,CAAC;IACJ,CAAC;CACF;AAjFD,oCAiFC"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const batcher_1 = require("@expo/batcher");
7
+ const entity_1 = require("@expo/entity");
8
+ const invariant_1 = __importDefault(require("invariant"));
9
+ const ioredis_1 = __importDefault(require("ioredis"));
10
+ const nullthrows_1 = __importDefault(require("nullthrows"));
11
+ const url_1 = require("url");
12
+ const uuid_1 = require("uuid");
13
+ const RedisCacheAdapter_1 = __importDefault(require("../RedisCacheAdapter"));
14
+ const RedisTestEntity_1 = __importDefault(require("../testfixtures/RedisTestEntity"));
15
+ const createRedisIntegrationTestEntityCompanionProvider_1 = require("../testfixtures/createRedisIntegrationTestEntityCompanionProvider");
16
+ class BatchedRedis {
17
+ constructor(redis) {
18
+ this.redis = redis;
19
+ this.mgetBatcher = new batcher_1.Batcher(this.batchMgetAsync.bind(this), {
20
+ maxBatchInterval: 0,
21
+ });
22
+ }
23
+ async batchMgetAsync(keySets) {
24
+ // ordered distinct keys to fetch
25
+ const allKeysToFetch = [...new Set(keySets.flat())];
26
+ // fetch the distinct keys
27
+ const allResults = await this.redis.mget(...allKeysToFetch);
28
+ // put them into a map for fast lookup
29
+ const keysToResults = (0, entity_1.zipToMap)(allKeysToFetch, allResults);
30
+ // re-associate them with original key sets
31
+ return keySets.map((keySet) => keySet.map((key) => {
32
+ const result = keysToResults.get(key);
33
+ (0, invariant_1.default)(result !== undefined, 'result should not be undefined');
34
+ return result;
35
+ }));
36
+ }
37
+ async mget(...args) {
38
+ return await this.mgetBatcher.batchAsync(args);
39
+ }
40
+ multi() {
41
+ return this.redis.multi();
42
+ }
43
+ async del(...args) {
44
+ await this.redis.del(...args);
45
+ }
46
+ }
47
+ describe(RedisCacheAdapter_1.default, () => {
48
+ const redis = new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString());
49
+ const redisClient = new BatchedRedis(redis);
50
+ let redisCacheAdapterContext;
51
+ beforeAll(() => {
52
+ redisCacheAdapterContext = {
53
+ redisClient,
54
+ makeKeyFn(...parts) {
55
+ const delimiter = ':';
56
+ const escapedParts = parts.map((part) => part.replace('\\', '\\\\').replace(delimiter, `\\${delimiter}`));
57
+ return escapedParts.join(delimiter);
58
+ },
59
+ cacheKeyPrefix: 'test-',
60
+ cacheKeyVersion: 1,
61
+ ttlSecondsPositive: 86400,
62
+ ttlSecondsNegative: 600, // 10 minutes
63
+ };
64
+ });
65
+ beforeEach(async () => {
66
+ await redis.flushdb();
67
+ });
68
+ afterAll(async () => {
69
+ redis.disconnect();
70
+ });
71
+ it('has correct caching behavior', async () => {
72
+ // simulate two requests
73
+ const viewerContext = new entity_1.ViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
74
+ const mgetSpy = jest.spyOn(redis, 'mget');
75
+ const cacheAdapter = viewerContext.entityCompanionProvider.getCompanionForEntity(RedisTestEntity_1.default, RedisTestEntity_1.default.getCompanionDefinition())['tableDataCoordinator']['cacheAdapter'];
76
+ const cacheKeyMaker = cacheAdapter['makeCacheKey'].bind(cacheAdapter);
77
+ const entity1Created = await RedisTestEntity_1.default.creator(viewerContext)
78
+ .setField('name', 'blah')
79
+ .enforceCreateAsync();
80
+ // loading an entity should put it in cache. load by multiple requests and multiple fields in same tick to ensure batch works
81
+ mgetSpy.mockClear();
82
+ const viewerContext1 = new entity_1.ViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
83
+ const viewerContext2 = new entity_1.ViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
84
+ const viewerContext3 = new entity_1.ViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
85
+ const [entity1, entity2, entity3] = await Promise.all([
86
+ RedisTestEntity_1.default.loader(viewerContext1).enforcing().loadByIDAsync(entity1Created.getID()),
87
+ RedisTestEntity_1.default.loader(viewerContext2).enforcing().loadByIDAsync(entity1Created.getID()),
88
+ RedisTestEntity_1.default.loader(viewerContext3)
89
+ .enforcing()
90
+ .loadByFieldEqualingAsync('name', entity1Created.getField('name')),
91
+ ]);
92
+ expect(mgetSpy).toHaveBeenCalledTimes(1);
93
+ expect(mgetSpy.mock.calls[0]).toHaveLength(2); // should dedupe the first two loads
94
+ expect(entity1.getID()).toEqual(entity2.getID());
95
+ expect(entity2.getID()).toEqual((0, nullthrows_1.default)(entity3).getID());
96
+ const cacheKeyEntity1 = cacheKeyMaker('id', entity1Created.getID());
97
+ const cachedJSON = await redis.get(cacheKeyEntity1);
98
+ const cachedValue = JSON.parse(cachedJSON);
99
+ expect(cachedValue).toMatchObject({
100
+ id: entity1.getID(),
101
+ name: 'blah',
102
+ });
103
+ const cacheKeyEntity1NameField = cacheKeyMaker('name', entity1Created.getField('name'));
104
+ await RedisTestEntity_1.default.loader(viewerContext)
105
+ .enforcing()
106
+ .loadByFieldEqualingAsync('name', entity1Created.getField('name'));
107
+ await expect(redis.get(cacheKeyEntity1NameField)).resolves.toEqual(cachedJSON);
108
+ // simulate non existent db fetch, should write negative result ('') to cache
109
+ const nonExistentId = (0, uuid_1.v4)();
110
+ const entityNonExistentResult = await RedisTestEntity_1.default.loader(viewerContext).loadByIDAsync(nonExistentId);
111
+ expect(entityNonExistentResult.ok).toBe(false);
112
+ const cacheKeyNonExistent = cacheKeyMaker('id', nonExistentId);
113
+ const nonExistentCachedValue = await redis.get(cacheKeyNonExistent);
114
+ expect(nonExistentCachedValue).toEqual('');
115
+ // load again through entities framework to ensure it reads negative result
116
+ const entityNonExistentResult2 = await RedisTestEntity_1.default.loader(viewerContext).loadByIDAsync(nonExistentId);
117
+ expect(entityNonExistentResult2.ok).toBe(false);
118
+ // invalidate from cache to ensure it invalidates correctly in both caches
119
+ await RedisTestEntity_1.default.loader(viewerContext).invalidateFieldsAsync(entity1.getAllFields());
120
+ await expect(redis.get(cacheKeyEntity1)).resolves.toBeNull();
121
+ await expect(redis.get(cacheKeyEntity1NameField)).resolves.toBeNull();
122
+ });
123
+ });
124
+ //# sourceMappingURL=BatchedRedisCacheAdapter-integration-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BatchedRedisCacheAdapter-integration-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/BatchedRedisCacheAdapter-integration-test.ts"],"names":[],"mappings":"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"}
@@ -35,10 +35,11 @@ const createRedisIntegrationTestEntityCompanionProvider_1 = require("../testfixt
35
35
  class TestViewerContext extends entity_1.ViewerContext {
36
36
  }
37
37
  describe(GenericRedisCacher_1.default, () => {
38
+ const redisClient = new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString());
38
39
  let redisCacheAdapterContext;
39
40
  beforeAll(() => {
40
41
  redisCacheAdapterContext = {
41
- redisClient: new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString()),
42
+ redisClient,
42
43
  makeKeyFn(...parts) {
43
44
  const delimiter = ':';
44
45
  const escapedParts = parts.map((part) => part.replace('\\', '\\\\').replace(delimiter, `\\${delimiter}`));
@@ -51,10 +52,10 @@ describe(GenericRedisCacher_1.default, () => {
51
52
  };
52
53
  });
53
54
  beforeEach(async () => {
54
- await redisCacheAdapterContext.redisClient.flushdb();
55
+ await redisClient.flushdb();
55
56
  });
56
57
  afterAll(async () => {
57
- redisCacheAdapterContext.redisClient.disconnect();
58
+ redisClient.disconnect();
58
59
  });
59
60
  it('has correct caching and loading behavior', async () => {
60
61
  const viewerContext = new TestViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
@@ -73,7 +74,7 @@ describe(GenericRedisCacher_1.default, () => {
73
74
  [testKey, entity1Created.getAllFields()],
74
75
  ]);
75
76
  await genericRedisCacher.cacheManyAsync(objectMap);
76
- const cachedJSON = await redisCacheAdapterContext.redisClient.get(testKey);
77
+ const cachedJSON = await redisClient.get(testKey);
77
78
  const cachedValue = JSON.parse(cachedJSON);
78
79
  expect(cachedValue).toMatchObject({
79
80
  id: entity1Created.getID(),
@@ -1 +1 @@
1
- {"version":3,"file":"GenericRedisCacher-integration-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/GenericRedisCacher-integration-test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GenericRedisCacher-integration-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/GenericRedisCacher-integration-test.ts"],"names":[],"mappings":"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"}
@@ -14,10 +14,11 @@ const createRedisIntegrationTestEntityCompanionProvider_1 = require("../testfixt
14
14
  class TestViewerContext extends entity_1.ViewerContext {
15
15
  }
16
16
  describe(RedisCacheAdapter_1.default, () => {
17
+ const redisClient = new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString());
17
18
  let redisCacheAdapterContext;
18
19
  beforeAll(() => {
19
20
  redisCacheAdapterContext = {
20
- redisClient: new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString()),
21
+ redisClient,
21
22
  makeKeyFn(...parts) {
22
23
  const delimiter = ':';
23
24
  const escapedParts = parts.map((part) => part.replace('\\', '\\\\').replace(delimiter, `\\${delimiter}`));
@@ -30,10 +31,10 @@ describe(RedisCacheAdapter_1.default, () => {
30
31
  };
31
32
  });
32
33
  beforeEach(async () => {
33
- await redisCacheAdapterContext.redisClient.flushdb();
34
+ await redisClient.flushdb();
34
35
  });
35
36
  afterAll(async () => {
36
- redisCacheAdapterContext.redisClient.disconnect();
37
+ redisClient.disconnect();
37
38
  });
38
39
  it('has correct caching behavior', async () => {
39
40
  const viewerContext = new TestViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
@@ -46,7 +47,7 @@ describe(RedisCacheAdapter_1.default, () => {
46
47
  const entity1 = await RedisTestEntity_1.default.loader(viewerContext)
47
48
  .enforcing()
48
49
  .loadByIDAsync(entity1Created.getID());
49
- const cachedJSON = await redisCacheAdapterContext.redisClient.get(cacheKeyMaker('id', entity1.getID()));
50
+ const cachedJSON = await redisClient.get(cacheKeyMaker('id', entity1.getID()));
50
51
  const cachedValue = JSON.parse(cachedJSON);
51
52
  expect(cachedValue).toMatchObject({
52
53
  id: entity1.getID(),
@@ -56,14 +57,14 @@ describe(RedisCacheAdapter_1.default, () => {
56
57
  const nonExistentId = (0, uuid_1.v4)();
57
58
  const entityNonExistentResult = await RedisTestEntity_1.default.loader(viewerContext).loadByIDAsync(nonExistentId);
58
59
  expect(entityNonExistentResult.ok).toBe(false);
59
- const nonExistentCachedValue = await redisCacheAdapterContext.redisClient.get(cacheKeyMaker('id', nonExistentId));
60
+ const nonExistentCachedValue = await redisClient.get(cacheKeyMaker('id', nonExistentId));
60
61
  expect(nonExistentCachedValue).toEqual('');
61
62
  // load again through entities framework to ensure it reads negative result
62
63
  const entityNonExistentResult2 = await RedisTestEntity_1.default.loader(viewerContext).loadByIDAsync(nonExistentId);
63
64
  expect(entityNonExistentResult2.ok).toBe(false);
64
65
  // invalidate from cache to ensure it invalidates correctly
65
66
  await RedisTestEntity_1.default.loader(viewerContext).invalidateFieldsAsync(entity1.getAllFields());
66
- const cachedValueNull = await redisCacheAdapterContext.redisClient.get(cacheKeyMaker('id', entity1.getID()));
67
+ const cachedValueNull = await redisClient.get(cacheKeyMaker('id', entity1.getID()));
67
68
  expect(cachedValueNull).toBe(null);
68
69
  });
69
70
  it('caches and restores date fields', async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"RedisCacheAdapter-integration-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/RedisCacheAdapter-integration-test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RedisCacheAdapter-integration-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/RedisCacheAdapter-integration-test.ts"],"names":[],"mappings":"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"}
@@ -12,10 +12,11 @@ const createRedisIntegrationTestEntityCompanionProvider_1 = require("../testfixt
12
12
  class TestViewerContext extends entity_1.ViewerContext {
13
13
  }
14
14
  describe(RedisCacheAdapter_1.default, () => {
15
+ const redisClient = new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString());
15
16
  let redisCacheAdapterContext;
16
17
  beforeAll(() => {
17
18
  redisCacheAdapterContext = {
18
- redisClient: new ioredis_1.default(new url_1.URL(process.env['REDIS_URL']).toString()),
19
+ redisClient,
19
20
  makeKeyFn(...parts) {
20
21
  const delimiter = ':';
21
22
  const escapedParts = parts.map((part) => part.replace('\\', '\\\\').replace(delimiter, `\\${delimiter}`));
@@ -28,10 +29,10 @@ describe(RedisCacheAdapter_1.default, () => {
28
29
  };
29
30
  });
30
31
  beforeEach(async () => {
31
- await redisCacheAdapterContext.redisClient.flushdb();
32
+ await redisClient.flushdb();
32
33
  });
33
34
  it('throws when redis is disconnected', async () => {
34
- redisCacheAdapterContext.redisClient.disconnect();
35
+ redisClient.disconnect();
35
36
  const vc1 = new TestViewerContext((0, createRedisIntegrationTestEntityCompanionProvider_1.createRedisIntegrationTestEntityCompanionProvider)(redisCacheAdapterContext));
36
37
  await expect(RedisTestEntity_1.default.creator(vc1).setField('name', 'blah').enforceCreateAsync()).rejects.toThrow(entity_1.EntityCacheAdapterTransientError);
37
38
  });
@@ -1 +1 @@
1
- {"version":3,"file":"errors-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/errors-test.ts"],"names":[],"mappings":";;;;;AAAA,yCAA+E;AAC/E,sDAA4B;AAC5B,6BAA0B;AAE1B,6EAAmF;AACnF,sFAA8D;AAC9D,yIAAsI;AAEtI,MAAM,iBAAkB,SAAQ,sBAAa;CAAG;AAEhD,QAAQ,CAAC,2BAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,wBAAkD,CAAC;IAEvD,SAAS,CAAC,GAAG,EAAE;QACb,wBAAwB,GAAG;YACzB,WAAW,EAAE,IAAI,iBAAK,CAAC,IAAI,SAAG,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YACrE,SAAS,CAAC,GAAG,KAAe;gBAC1B,MAAM,SAAS,GAAG,GAAG,CAAC;gBACtB,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACtC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,SAAS,EAAE,CAAC,CAChE,CAAC;gBACF,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;YACD,cAAc,EAAE,OAAO;YACvB,eAAe,EAAE,CAAC;YAClB,kBAAkB,EAAE,KAAK;YACzB,kBAAkB,EAAE,GAAG,EAAE,aAAa;SACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,wBAAwB,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,wBAAwB,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAElD,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAC/B,IAAA,qGAAiD,EAAC,wBAAwB,CAAC,CAC5E,CAAC;QAEF,MAAM,MAAM,CACV,yBAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,kBAAkB,EAAE,CAC3E,CAAC,OAAO,CAAC,OAAO,CAAC,yCAAgC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"errors-test.js","sourceRoot":"","sources":["../../src/__integration-tests__/errors-test.ts"],"names":[],"mappings":";;;;;AAAA,yCAA+E;AAC/E,sDAA4B;AAC5B,6BAA0B;AAE1B,6EAAmF;AACnF,sFAA8D;AAC9D,yIAAsI;AAEtI,MAAM,iBAAkB,SAAQ,sBAAa;CAAG;AAEhD,QAAQ,CAAC,2BAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,WAAW,GAAG,IAAI,iBAAK,CAAC,IAAI,SAAG,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7E,IAAI,wBAAkD,CAAC;IAEvD,SAAS,CAAC,GAAG,EAAE;QACb,wBAAwB,GAAG;YACzB,WAAW;YACX,SAAS,CAAC,GAAG,KAAe;gBAC1B,MAAM,SAAS,GAAG,GAAG,CAAC;gBACtB,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACtC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,SAAS,EAAE,CAAC,CAChE,CAAC;gBACF,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;YACD,cAAc,EAAE,OAAO;YACvB,eAAe,EAAE,CAAC;YAClB,kBAAkB,EAAE,KAAK;YACzB,kBAAkB,EAAE,GAAG,EAAE,aAAa;SACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,WAAW,CAAC,UAAU,EAAE,CAAC;QAEzB,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAC/B,IAAA,qGAAiD,EAAC,wBAAwB,CAAC,CAC5E,CAAC;QAEF,MAAM,MAAM,CACV,yBAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,kBAAkB,EAAE,CAC3E,CAAC,OAAO,CAAC,OAAO,CAAC,yCAAgC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -6,12 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createRedisIntegrationTestEntityCompanionProvider = void 0;
7
7
  const entity_1 = require("@expo/entity");
8
8
  const RedisCacheAdapterProvider_1 = __importDefault(require("../RedisCacheAdapterProvider"));
9
+ // share across all in calls in test to simulate postgres
10
+ const adapterProvider = new entity_1.StubDatabaseAdapterProvider();
9
11
  const createRedisIntegrationTestEntityCompanionProvider = (redisCacheAdapterContext, metricsAdapter = new entity_1.NoOpEntityMetricsAdapter()) => {
10
12
  return new entity_1.EntityCompanionProvider(metricsAdapter, new Map([
11
13
  [
12
14
  'postgres',
13
15
  {
14
- adapterProvider: new entity_1.StubDatabaseAdapterProvider(),
16
+ adapterProvider,
15
17
  queryContextProvider: entity_1.StubQueryContextProvider,
16
18
  },
17
19
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"createRedisIntegrationTestEntityCompanionProvider.js","sourceRoot":"","sources":["../../src/testfixtures/createRedisIntegrationTestEntityCompanionProvider.ts"],"names":[],"mappings":";;;;;;AAAA,yCAMsB;AAGtB,6FAAqE;AAE9D,MAAM,iDAAiD,GAAG,CAC/D,wBAAkD,EAClD,iBAAwC,IAAI,iCAAwB,EAAE,EAC7C,EAAE;IAC3B,OAAO,IAAI,gCAAuB,CAChC,cAAc,EACd,IAAI,GAAG,CAAC;QACN;YACE,UAAU;YACV;gBACE,eAAe,EAAE,IAAI,oCAA2B,EAAE;gBAClD,oBAAoB,EAAE,iCAAwB;aAC/C;SACF;KACF,CAAC,EACF,IAAI,GAAG,CAAC;QACN;YACE,OAAO;YACP;gBACE,oBAAoB,EAAE,IAAI,mCAAyB,CAAC,wBAAwB,CAAC;aAC9E;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAxBW,QAAA,iDAAiD,qDAwB5D"}
1
+ {"version":3,"file":"createRedisIntegrationTestEntityCompanionProvider.js","sourceRoot":"","sources":["../../src/testfixtures/createRedisIntegrationTestEntityCompanionProvider.ts"],"names":[],"mappings":";;;;;;AAAA,yCAMsB;AAGtB,6FAAqE;AAErE,yDAAyD;AACzD,MAAM,eAAe,GAAG,IAAI,oCAA2B,EAAE,CAAC;AAEnD,MAAM,iDAAiD,GAAG,CAC/D,wBAAkD,EAClD,iBAAwC,IAAI,iCAAwB,EAAE,EAC7C,EAAE;IAC3B,OAAO,IAAI,gCAAuB,CAChC,cAAc,EACd,IAAI,GAAG,CAAC;QACN;YACE,UAAU;YACV;gBACE,eAAe;gBACf,oBAAoB,EAAE,iCAAwB;aAC/C;SACF;KACF,CAAC,EACF,IAAI,GAAG,CAAC;QACN;YACE,OAAO;YACP;gBACE,oBAAoB,EAAE,IAAI,mCAAyB,CAAC,wBAAwB,CAAC;aAC9E;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAxBW,QAAA,iDAAiD,qDAwB5D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/entity-cache-adapter-redis",
3
- "version": "0.28.0",
3
+ "version": "0.30.0",
4
4
  "description": "Redis cache adapter for @expo/entity",
5
5
  "files": [
6
6
  "build",
@@ -31,8 +31,8 @@
31
31
  "ioredis": ">=5"
32
32
  },
33
33
  "devDependencies": {
34
- "@expo/entity": "^0.28.0",
34
+ "@expo/entity": "^0.30.0",
35
35
  "ioredis": "^5.0.4"
36
36
  },
37
- "gitHead": "dbf1e030394d1f2bdf58d858cb455be9136a1b14"
37
+ "gitHead": "abd86b91d344e4367b6acd416ab0e5ee3704cb1a"
38
38
  }
@@ -6,7 +6,6 @@ import {
6
6
  transformFieldsToCacheObject,
7
7
  IEntityGenericCacher,
8
8
  } from '@expo/entity';
9
- import { Redis } from 'ioredis';
10
9
 
11
10
  import { redisTransformerMap } from './RedisCommon';
12
11
  import wrapNativeRedisCallAsync from './errors/wrapNativeRedisCallAsync';
@@ -15,11 +14,22 @@ import wrapNativeRedisCallAsync from './errors/wrapNativeRedisCallAsync';
15
14
  // The sentinel value is distinct from any (positively) cached value.
16
15
  const DOES_NOT_EXIST_REDIS = '';
17
16
 
17
+ export interface IRedisTransaction {
18
+ set(key: string, value: string, secondsToken: 'EX', seconds: number): this;
19
+ exec(): Promise<any>;
20
+ }
21
+
22
+ export interface IRedis {
23
+ mget(...args: [...keys: string[]]): Promise<(string | null)[]>;
24
+ multi(): IRedisTransaction;
25
+ del(...args: [...keys: string[]]): Promise<any>;
26
+ }
27
+
18
28
  export interface GenericRedisCacheContext {
19
29
  /**
20
30
  * Instance of ioredis.Redis
21
31
  */
22
- redisClient: Redis;
32
+ redisClient: IRedis;
23
33
 
24
34
  /**
25
35
  * TTL for caching database hits. Successive entity loads within this TTL
@@ -1,14 +1,13 @@
1
1
  import { EntityCacheAdapter, EntityConfiguration, CacheLoadResult, mapKeys } from '@expo/entity';
2
2
  import invariant from 'invariant';
3
- import type { Redis } from 'ioredis';
4
3
 
5
- import GenericRedisCacher from './GenericRedisCacher';
4
+ import GenericRedisCacher, { IRedis } from './GenericRedisCacher';
6
5
 
7
6
  export interface RedisCacheAdapterContext {
8
7
  /**
9
8
  * Instance of ioredis.Redis
10
9
  */
11
- redisClient: Redis;
10
+ redisClient: IRedis;
12
11
 
13
12
  /**
14
13
  * Create a key string for key parts (cache key prefix, versions, entity name, etc).
@@ -0,0 +1,164 @@
1
+ import { Batcher } from '@expo/batcher';
2
+ import { ViewerContext, zipToMap } from '@expo/entity';
3
+ import invariant from 'invariant';
4
+ import Redis from 'ioredis';
5
+ import nullthrows from 'nullthrows';
6
+ import { URL } from 'url';
7
+ import { v4 as uuidv4 } from 'uuid';
8
+
9
+ import { IRedis, IRedisTransaction } from '../GenericRedisCacher';
10
+ import RedisCacheAdapter, { RedisCacheAdapterContext } from '../RedisCacheAdapter';
11
+ import RedisTestEntity from '../testfixtures/RedisTestEntity';
12
+ import { createRedisIntegrationTestEntityCompanionProvider } from '../testfixtures/createRedisIntegrationTestEntityCompanionProvider';
13
+
14
+ class BatchedRedis implements IRedis {
15
+ private readonly mgetBatcher = new Batcher<string[], (string | null)[]>(
16
+ this.batchMgetAsync.bind(this),
17
+ {
18
+ maxBatchInterval: 0,
19
+ }
20
+ );
21
+
22
+ constructor(private readonly redis: Redis) {}
23
+
24
+ private async batchMgetAsync(keySets: string[][]): Promise<(string | null)[][]> {
25
+ // ordered distinct keys to fetch
26
+ const allKeysToFetch = [...new Set(keySets.flat())];
27
+
28
+ // fetch the distinct keys
29
+ const allResults = await this.redis.mget(...allKeysToFetch);
30
+
31
+ // put them into a map for fast lookup
32
+ const keysToResults = zipToMap(allKeysToFetch, allResults);
33
+
34
+ // re-associate them with original key sets
35
+ return keySets.map((keySet) =>
36
+ keySet.map((key) => {
37
+ const result = keysToResults.get(key);
38
+ invariant(result !== undefined, 'result should not be undefined');
39
+ return result;
40
+ })
41
+ );
42
+ }
43
+
44
+ async mget(...args: string[]): Promise<(string | null)[]> {
45
+ return await this.mgetBatcher.batchAsync(args);
46
+ }
47
+
48
+ multi(): IRedisTransaction {
49
+ return this.redis.multi();
50
+ }
51
+
52
+ async del(...args: string[]): Promise<void> {
53
+ await this.redis.del(...args);
54
+ }
55
+ }
56
+
57
+ describe(RedisCacheAdapter, () => {
58
+ const redis = new Redis(new URL(process.env['REDIS_URL']!).toString());
59
+ const redisClient = new BatchedRedis(redis);
60
+
61
+ let redisCacheAdapterContext: RedisCacheAdapterContext;
62
+
63
+ beforeAll(() => {
64
+ redisCacheAdapterContext = {
65
+ redisClient,
66
+ makeKeyFn(...parts: string[]): string {
67
+ const delimiter = ':';
68
+ const escapedParts = parts.map((part) =>
69
+ part.replace('\\', '\\\\').replace(delimiter, `\\${delimiter}`)
70
+ );
71
+ return escapedParts.join(delimiter);
72
+ },
73
+ cacheKeyPrefix: 'test-',
74
+ cacheKeyVersion: 1,
75
+ ttlSecondsPositive: 86400, // 1 day
76
+ ttlSecondsNegative: 600, // 10 minutes
77
+ };
78
+ });
79
+
80
+ beforeEach(async () => {
81
+ await redis.flushdb();
82
+ });
83
+
84
+ afterAll(async () => {
85
+ redis.disconnect();
86
+ });
87
+
88
+ it('has correct caching behavior', async () => {
89
+ // simulate two requests
90
+ const viewerContext = new ViewerContext(
91
+ createRedisIntegrationTestEntityCompanionProvider(redisCacheAdapterContext)
92
+ );
93
+
94
+ const mgetSpy = jest.spyOn(redis, 'mget');
95
+
96
+ const cacheAdapter = viewerContext.entityCompanionProvider.getCompanionForEntity(
97
+ RedisTestEntity,
98
+ RedisTestEntity.getCompanionDefinition()
99
+ )['tableDataCoordinator']['cacheAdapter'];
100
+ const cacheKeyMaker = cacheAdapter['makeCacheKey'].bind(cacheAdapter);
101
+
102
+ const entity1Created = await RedisTestEntity.creator(viewerContext)
103
+ .setField('name', 'blah')
104
+ .enforceCreateAsync();
105
+
106
+ // loading an entity should put it in cache. load by multiple requests and multiple fields in same tick to ensure batch works
107
+ mgetSpy.mockClear();
108
+ const viewerContext1 = new ViewerContext(
109
+ createRedisIntegrationTestEntityCompanionProvider(redisCacheAdapterContext)
110
+ );
111
+ const viewerContext2 = new ViewerContext(
112
+ createRedisIntegrationTestEntityCompanionProvider(redisCacheAdapterContext)
113
+ );
114
+ const viewerContext3 = new ViewerContext(
115
+ createRedisIntegrationTestEntityCompanionProvider(redisCacheAdapterContext)
116
+ );
117
+ const [entity1, entity2, entity3] = await Promise.all([
118
+ RedisTestEntity.loader(viewerContext1).enforcing().loadByIDAsync(entity1Created.getID()),
119
+ RedisTestEntity.loader(viewerContext2).enforcing().loadByIDAsync(entity1Created.getID()),
120
+ RedisTestEntity.loader(viewerContext3)
121
+ .enforcing()
122
+ .loadByFieldEqualingAsync('name', entity1Created.getField('name')),
123
+ ]);
124
+
125
+ expect(mgetSpy).toHaveBeenCalledTimes(1);
126
+ expect(mgetSpy.mock.calls[0]).toHaveLength(2); // should dedupe the first two loads
127
+ expect(entity1.getID()).toEqual(entity2.getID());
128
+ expect(entity2.getID()).toEqual(nullthrows(entity3).getID());
129
+
130
+ const cacheKeyEntity1 = cacheKeyMaker('id', entity1Created.getID());
131
+ const cachedJSON = await redis.get(cacheKeyEntity1);
132
+ const cachedValue = JSON.parse(cachedJSON!);
133
+ expect(cachedValue).toMatchObject({
134
+ id: entity1.getID(),
135
+ name: 'blah',
136
+ });
137
+
138
+ const cacheKeyEntity1NameField = cacheKeyMaker('name', entity1Created.getField('name'));
139
+ await RedisTestEntity.loader(viewerContext)
140
+ .enforcing()
141
+ .loadByFieldEqualingAsync('name', entity1Created.getField('name'));
142
+ await expect(redis.get(cacheKeyEntity1NameField)).resolves.toEqual(cachedJSON);
143
+
144
+ // simulate non existent db fetch, should write negative result ('') to cache
145
+ const nonExistentId = uuidv4();
146
+ const entityNonExistentResult = await RedisTestEntity.loader(viewerContext).loadByIDAsync(
147
+ nonExistentId
148
+ );
149
+ expect(entityNonExistentResult.ok).toBe(false);
150
+ const cacheKeyNonExistent = cacheKeyMaker('id', nonExistentId);
151
+ const nonExistentCachedValue = await redis.get(cacheKeyNonExistent);
152
+ expect(nonExistentCachedValue).toEqual('');
153
+ // load again through entities framework to ensure it reads negative result
154
+ const entityNonExistentResult2 = await RedisTestEntity.loader(viewerContext).loadByIDAsync(
155
+ nonExistentId
156
+ );
157
+ expect(entityNonExistentResult2.ok).toBe(false);
158
+
159
+ // invalidate from cache to ensure it invalidates correctly in both caches
160
+ await RedisTestEntity.loader(viewerContext).invalidateFieldsAsync(entity1.getAllFields());
161
+ await expect(redis.get(cacheKeyEntity1)).resolves.toBeNull();
162
+ await expect(redis.get(cacheKeyEntity1NameField)).resolves.toBeNull();
163
+ });
164
+ });
@@ -13,11 +13,12 @@ import { createRedisIntegrationTestEntityCompanionProvider } from '../testfixtur
13
13
  class TestViewerContext extends ViewerContext {}
14
14
 
15
15
  describe(GenericRedisCacher, () => {
16
+ const redisClient = new Redis(new URL(process.env['REDIS_URL']!).toString());
16
17
  let redisCacheAdapterContext: RedisCacheAdapterContext;
17
18
 
18
19
  beforeAll(() => {
19
20
  redisCacheAdapterContext = {
20
- redisClient: new Redis(new URL(process.env['REDIS_URL']!).toString()),
21
+ redisClient,
21
22
  makeKeyFn(...parts: string[]): string {
22
23
  const delimiter = ':';
23
24
  const escapedParts = parts.map((part) =>
@@ -33,10 +34,10 @@ describe(GenericRedisCacher, () => {
33
34
  });
34
35
 
35
36
  beforeEach(async () => {
36
- await redisCacheAdapterContext.redisClient.flushdb();
37
+ await redisClient.flushdb();
37
38
  });
38
39
  afterAll(async () => {
39
- redisCacheAdapterContext.redisClient.disconnect();
40
+ redisClient.disconnect();
40
41
  });
41
42
 
42
43
  it('has correct caching and loading behavior', async () => {
@@ -62,7 +63,7 @@ describe(GenericRedisCacher, () => {
62
63
  ]);
63
64
  await genericRedisCacher.cacheManyAsync(objectMap);
64
65
 
65
- const cachedJSON = await redisCacheAdapterContext.redisClient.get(testKey);
66
+ const cachedJSON = await redisClient.get(testKey);
66
67
  const cachedValue = JSON.parse(cachedJSON!);
67
68
  expect(cachedValue).toMatchObject({
68
69
  id: entity1Created.getID(),
@@ -11,11 +11,12 @@ import { createRedisIntegrationTestEntityCompanionProvider } from '../testfixtur
11
11
  class TestViewerContext extends ViewerContext {}
12
12
 
13
13
  describe(RedisCacheAdapter, () => {
14
+ const redisClient = new Redis(new URL(process.env['REDIS_URL']!).toString());
14
15
  let redisCacheAdapterContext: RedisCacheAdapterContext;
15
16
 
16
17
  beforeAll(() => {
17
18
  redisCacheAdapterContext = {
18
- redisClient: new Redis(new URL(process.env['REDIS_URL']!).toString()),
19
+ redisClient,
19
20
  makeKeyFn(...parts: string[]): string {
20
21
  const delimiter = ':';
21
22
  const escapedParts = parts.map((part) =>
@@ -31,10 +32,10 @@ describe(RedisCacheAdapter, () => {
31
32
  });
32
33
 
33
34
  beforeEach(async () => {
34
- await redisCacheAdapterContext.redisClient.flushdb();
35
+ await redisClient.flushdb();
35
36
  });
36
37
  afterAll(async () => {
37
- redisCacheAdapterContext.redisClient.disconnect();
38
+ redisClient.disconnect();
38
39
  });
39
40
 
40
41
  it('has correct caching behavior', async () => {
@@ -56,9 +57,7 @@ describe(RedisCacheAdapter, () => {
56
57
  .enforcing()
57
58
  .loadByIDAsync(entity1Created.getID());
58
59
 
59
- const cachedJSON = await redisCacheAdapterContext.redisClient.get(
60
- cacheKeyMaker('id', entity1.getID())
61
- );
60
+ const cachedJSON = await redisClient.get(cacheKeyMaker('id', entity1.getID()));
62
61
  const cachedValue = JSON.parse(cachedJSON!);
63
62
  expect(cachedValue).toMatchObject({
64
63
  id: entity1.getID(),
@@ -73,9 +72,7 @@ describe(RedisCacheAdapter, () => {
73
72
  );
74
73
  expect(entityNonExistentResult.ok).toBe(false);
75
74
 
76
- const nonExistentCachedValue = await redisCacheAdapterContext.redisClient.get(
77
- cacheKeyMaker('id', nonExistentId)
78
- );
75
+ const nonExistentCachedValue = await redisClient.get(cacheKeyMaker('id', nonExistentId));
79
76
  expect(nonExistentCachedValue).toEqual('');
80
77
 
81
78
  // load again through entities framework to ensure it reads negative result
@@ -86,9 +83,7 @@ describe(RedisCacheAdapter, () => {
86
83
 
87
84
  // invalidate from cache to ensure it invalidates correctly
88
85
  await RedisTestEntity.loader(viewerContext).invalidateFieldsAsync(entity1.getAllFields());
89
- const cachedValueNull = await redisCacheAdapterContext.redisClient.get(
90
- cacheKeyMaker('id', entity1.getID())
91
- );
86
+ const cachedValueNull = await redisClient.get(cacheKeyMaker('id', entity1.getID()));
92
87
  expect(cachedValueNull).toBe(null);
93
88
  });
94
89
 
@@ -9,11 +9,12 @@ import { createRedisIntegrationTestEntityCompanionProvider } from '../testfixtur
9
9
  class TestViewerContext extends ViewerContext {}
10
10
 
11
11
  describe(RedisCacheAdapter, () => {
12
+ const redisClient = new Redis(new URL(process.env['REDIS_URL']!).toString());
12
13
  let redisCacheAdapterContext: RedisCacheAdapterContext;
13
14
 
14
15
  beforeAll(() => {
15
16
  redisCacheAdapterContext = {
16
- redisClient: new Redis(new URL(process.env['REDIS_URL']!).toString()),
17
+ redisClient,
17
18
  makeKeyFn(...parts: string[]): string {
18
19
  const delimiter = ':';
19
20
  const escapedParts = parts.map((part) =>
@@ -29,11 +30,11 @@ describe(RedisCacheAdapter, () => {
29
30
  });
30
31
 
31
32
  beforeEach(async () => {
32
- await redisCacheAdapterContext.redisClient.flushdb();
33
+ await redisClient.flushdb();
33
34
  });
34
35
 
35
36
  it('throws when redis is disconnected', async () => {
36
- redisCacheAdapterContext.redisClient.disconnect();
37
+ redisClient.disconnect();
37
38
 
38
39
  const vc1 = new TestViewerContext(
39
40
  createRedisIntegrationTestEntityCompanionProvider(redisCacheAdapterContext)
@@ -9,6 +9,9 @@ import {
9
9
  import { RedisCacheAdapterContext } from '../RedisCacheAdapter';
10
10
  import RedisCacheAdapterProvider from '../RedisCacheAdapterProvider';
11
11
 
12
+ // share across all in calls in test to simulate postgres
13
+ const adapterProvider = new StubDatabaseAdapterProvider();
14
+
12
15
  export const createRedisIntegrationTestEntityCompanionProvider = (
13
16
  redisCacheAdapterContext: RedisCacheAdapterContext,
14
17
  metricsAdapter: IEntityMetricsAdapter = new NoOpEntityMetricsAdapter()
@@ -19,7 +22,7 @@ export const createRedisIntegrationTestEntityCompanionProvider = (
19
22
  [
20
23
  'postgres',
21
24
  {
22
- adapterProvider: new StubDatabaseAdapterProvider(),
25
+ adapterProvider,
23
26
  queryContextProvider: StubQueryContextProvider,
24
27
  },
25
28
  ],