Skip to content

Commit 7323f74

Browse files
author
vrazuvaev
committed
pivot: remove public API, add autoEvict per partition
1 parent 1d31f33 commit 7323f74

File tree

5 files changed

+160
-288
lines changed

5 files changed

+160
-288
lines changed

packages/apollo-forest-run/src/ForestRun.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import type { OperationDescriptor } from "./descriptor/types";
1010
import type {
1111
CacheConfig,
1212
CacheEnv,
13-
ClearPartitionOptions,
1413
DataForest,
1514
HistoryPartitions,
1615
OptimisticLayer,
@@ -26,12 +25,11 @@ import { read } from "./cache/read";
2625
import { getNodeChunks } from "./cache/draftHelpers";
2726
import { modify } from "./cache/modify";
2827
import {
29-
clearPartitionData,
3028
createOptimisticLayer,
3129
createStore,
3230
evictOldData,
3331
getEffectiveReadLayers,
34-
maybeEvictOldData,
32+
maybeAutoEvict,
3533
removeOptimisticLayers,
3634
resetStore,
3735
} from "./cache/store";
@@ -459,10 +457,6 @@ export class ForestRun<
459457
return [];
460458
}
461459

462-
public clearPartition(options: ClearPartitionOptions): string[] {
463-
return clearPartitionData(this.env, this.store, options).map(String);
464-
}
465-
466460
public getStats() {
467461
return {
468462
docCount: this.store.operations.size,
@@ -585,7 +579,7 @@ export class ForestRun<
585579
);
586580
logUpdateStats(this.env, activeTransaction.changelog, watchesToNotify);
587581
}
588-
maybeEvictOldData(this.env, this.store);
582+
maybeAutoEvict(this.env, this.store, activeTransaction);
589583

590584
return result as T;
591585
}

packages/apollo-forest-run/src/__tests__/eviction.test.ts

Lines changed: 56 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { ForestRun } from "../ForestRun";
2-
import { PartitionConfig } from "../cache/types";
32
import { gql } from "./helpers/descriptor";
43

54
it("evicts data automatically by default", () => {
@@ -305,20 +304,17 @@ it("should warn exactly once for the same warning", () => {
305304
// notably: "query TestB" is NOT logged
306305
});
307306

308-
describe("clearPartition", () => {
309-
const partitionConfig: PartitionConfig = {
310-
partitionKey: (o) => o.operation.debugName,
311-
partitions: {
312-
"query a": { maxOperationCount: 10 },
313-
"query b": { maxOperationCount: 10 },
314-
},
315-
};
316-
317-
it("clears all ops in a partition", () => {
307+
describe("partition autoEvict", () => {
308+
it("auto-evicts partition on write when partition.autoEvict is true", () => {
318309
const cache = new ForestRun({
319310
maxOperationCount: 100,
320311
autoEvict: false,
321-
unstable_partitionConfig: partitionConfig,
312+
unstable_partitionConfig: {
313+
partitionKey: (o) => o.operation.debugName,
314+
partitions: {
315+
"query a": { maxOperationCount: 1, autoEvict: true },
316+
},
317+
},
322318
});
323319
const a = gql`
324320
query a($i: Int) {
@@ -328,26 +324,26 @@ describe("clearPartition", () => {
328324

329325
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
330326
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
331-
cache.write({ query: a, variables: { i: 2 }, result: { foo: 2 } });
332-
333-
cache.clearPartition({ partition: "query a" });
334327

328+
// Only most recent survives
335329
expect(
336330
cache.read({ query: a, variables: { i: 0 }, optimistic: true }),
337331
).toEqual(null);
338332
expect(
339333
cache.read({ query: a, variables: { i: 1 }, optimistic: true }),
340-
).toEqual(null);
341-
expect(
342-
cache.read({ query: a, variables: { i: 2 }, optimistic: true }),
343-
).toEqual(null);
334+
).toEqual({ foo: 1 });
344335
});
345336

346-
it("keepMostRecent preserves N most recent ops", () => {
337+
it("does not auto-evict partition when autoEvict is not set", () => {
347338
const cache = new ForestRun({
348339
maxOperationCount: 100,
349340
autoEvict: false,
350-
unstable_partitionConfig: partitionConfig,
341+
unstable_partitionConfig: {
342+
partitionKey: (o) => o.operation.debugName,
343+
partitions: {
344+
"query a": { maxOperationCount: 1 },
345+
},
346+
},
351347
});
352348
const a = gql`
353349
query a($i: Int) {
@@ -357,27 +353,27 @@ describe("clearPartition", () => {
357353

358354
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
359355
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
360-
cache.write({ query: a, variables: { i: 2 }, result: { foo: 2 } });
361-
362-
cache.clearPartition({ partition: "query a", keepMostRecent: 1 });
363356

357+
// Both survive — no auto-eviction
364358
expect(
365359
cache.read({ query: a, variables: { i: 0 }, optimistic: true }),
366-
).toEqual(null);
360+
).toEqual({ foo: 0 });
367361
expect(
368362
cache.read({ query: a, variables: { i: 1 }, optimistic: true }),
369-
).toEqual(null);
370-
// Most recent survives
371-
expect(
372-
cache.read({ query: a, variables: { i: 2 }, optimistic: true }),
373-
).toEqual({ foo: 2 });
363+
).toEqual({ foo: 1 });
374364
});
375365

376366
it("doesn't touch other partitions", () => {
377367
const cache = new ForestRun({
378368
maxOperationCount: 100,
379369
autoEvict: false,
380-
unstable_partitionConfig: partitionConfig,
370+
unstable_partitionConfig: {
371+
partitionKey: (o) => o.operation.debugName,
372+
partitions: {
373+
"query a": { maxOperationCount: 1, autoEvict: true },
374+
"query b": { maxOperationCount: 10 },
375+
},
376+
},
381377
});
382378
const a = gql`
383379
query a($i: Int) {
@@ -390,15 +386,19 @@ describe("clearPartition", () => {
390386
}
391387
`;
392388

393-
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
394389
cache.write({ query: b, variables: { i: 0 }, result: { bar: 0 } });
395390
cache.write({ query: b, variables: { i: 1 }, result: { bar: 1 } });
391+
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
392+
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
396393

397-
cache.clearPartition({ partition: "query a" });
398-
394+
// partition a evicted down to 1
399395
expect(
400396
cache.read({ query: a, variables: { i: 0 }, optimistic: true }),
401397
).toEqual(null);
398+
expect(
399+
cache.read({ query: a, variables: { i: 1 }, optimistic: true }),
400+
).toEqual({ foo: 1 });
401+
// partition b untouched
402402
expect(
403403
cache.read({ query: b, variables: { i: 0 }, optimistic: true }),
404404
).toEqual({ bar: 0 });
@@ -407,11 +407,16 @@ describe("clearPartition", () => {
407407
).toEqual({ bar: 1 });
408408
});
409409

410-
it("skips watched ops by default", () => {
410+
it("skips watched ops during partition auto-eviction", () => {
411411
const cache = new ForestRun({
412412
maxOperationCount: 100,
413413
autoEvict: false,
414-
unstable_partitionConfig: partitionConfig,
414+
unstable_partitionConfig: {
415+
partitionKey: (o) => o.operation.debugName,
416+
partitions: {
417+
"query a": { maxOperationCount: 1, autoEvict: true },
418+
},
419+
},
415420
});
416421
const a = gql`
417422
query a($i: Int) {
@@ -421,7 +426,7 @@ describe("clearPartition", () => {
421426

422427
cache.watch({
423428
query: a,
424-
variables: { i: 1 },
429+
variables: { i: 0 },
425430
optimistic: true,
426431
callback: () => {},
427432
});
@@ -430,154 +435,46 @@ describe("clearPartition", () => {
430435
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
431436
cache.write({ query: a, variables: { i: 2 }, result: { foo: 2 } });
432437

433-
cache.clearPartition({ partition: "query a" });
434-
438+
// Watched op survives, most recent survives
435439
expect(
436440
cache.read({ query: a, variables: { i: 0 }, optimistic: true }),
437-
).toEqual(null);
438-
// Watched — survives
439-
expect(
440-
cache.read({ query: a, variables: { i: 1 }, optimistic: true }),
441-
).toEqual({ foo: 1 });
442-
expect(
443-
cache.read({ query: a, variables: { i: 2 }, optimistic: true }),
444-
).toEqual(null);
445-
});
446-
447-
it("includeWatched clears watched ops too", () => {
448-
const cache = new ForestRun({
449-
maxOperationCount: 100,
450-
autoEvict: false,
451-
unstable_partitionConfig: partitionConfig,
452-
});
453-
const a = gql`
454-
query a($i: Int) {
455-
foo(i: $i)
456-
}
457-
`;
458-
459-
cache.watch({
460-
query: a,
461-
variables: { i: 1 },
462-
optimistic: true,
463-
callback: () => {},
464-
});
465-
466-
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
467-
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
468-
cache.write({ query: a, variables: { i: 2 }, result: { foo: 2 } });
469-
470-
cache.clearPartition({
471-
partition: "query a",
472-
includeWatched: true,
473-
});
474-
475-
expect(
476-
cache.read({ query: a, variables: { i: 0 }, optimistic: true }),
477-
).toEqual(null);
478-
expect(
479-
cache.read({ query: a, variables: { i: 1 }, optimistic: true }),
480-
).toEqual(null);
441+
).toEqual({ foo: 0 });
481442
expect(
482443
cache.read({ query: a, variables: { i: 2 }, optimistic: true }),
483-
).toEqual(null);
484-
});
485-
486-
it("warns and returns empty for unconfigured partition name", () => {
487-
const mockConsole = { ...console, warn: jest.fn() };
488-
const cache = new ForestRun({
489-
maxOperationCount: 100,
490-
autoEvict: false,
491-
logger: mockConsole,
492-
unstable_partitionConfig: partitionConfig,
493-
});
494-
495-
const result = cache.clearPartition({ partition: "nonexistent" });
496-
497-
expect(result).toEqual([]);
498-
expect(mockConsole.warn).toHaveBeenCalledTimes(1);
499-
});
500-
501-
it("warns and returns empty when no partitionConfig", () => {
502-
const mockConsole = { ...console, warn: jest.fn() };
503-
const cache = new ForestRun({
504-
maxOperationCount: 100,
505-
autoEvict: false,
506-
logger: mockConsole,
507-
});
508-
509-
const result = cache.clearPartition({ partition: "anything" });
510-
511-
expect(result).toEqual([]);
512-
expect(mockConsole.warn).toHaveBeenCalledTimes(1);
513-
});
514-
515-
it("returns evicted operation IDs as string[]", () => {
516-
const cache = new ForestRun({
517-
maxOperationCount: 100,
518-
autoEvict: false,
519-
unstable_partitionConfig: partitionConfig,
520-
});
521-
const a = gql`
522-
query a($i: Int) {
523-
foo(i: $i)
524-
}
525-
`;
526-
527-
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
528-
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
529-
530-
const result = cache.clearPartition({ partition: "query a" });
531-
532-
expect(result).toHaveLength(2);
533-
expect(result.every((id) => typeof id === "string")).toBe(true);
444+
).toEqual({ foo: 2 });
534445
});
535446

536-
it("respects nonEvictableQueries even with includeWatched", () => {
447+
it("respects nonEvictableQueries during partition auto-eviction", () => {
537448
const cache = new ForestRun({
538449
maxOperationCount: 100,
539450
autoEvict: false,
540451
nonEvictableQueries: new Set(["foo"]),
541-
unstable_partitionConfig: partitionConfig,
452+
unstable_partitionConfig: {
453+
partitionKey: (o) => o.operation.debugName,
454+
partitions: {
455+
"query a": { maxOperationCount: 1, autoEvict: true },
456+
},
457+
},
542458
});
543459
const a = gql`
544460
query a($i: Int) {
545461
foo(i: $i)
546462
}
547463
`;
548-
const b = gql`
549-
query b($i: Int) {
550-
bar(i: $i)
551-
}
552-
`;
553-
554-
cache.watch({
555-
query: a,
556-
variables: { i: 0 },
557-
optimistic: true,
558-
callback: () => {},
559-
});
560464

561465
cache.write({ query: a, variables: { i: 0 }, result: { foo: 0 } });
562466
cache.write({ query: a, variables: { i: 1 }, result: { foo: 1 } });
563-
cache.write({ query: b, variables: { i: 0 }, result: { bar: 0 } });
564-
565-
const result = cache.clearPartition({
566-
partition: "query a",
567-
includeWatched: true,
568-
});
467+
cache.write({ query: a, variables: { i: 2 }, result: { foo: 2 } });
569468

570-
// "foo" is nonEvictable — both query a ops survive despite includeWatched
571-
expect(result).toEqual([]);
469+
// All survive — nonEvictableQueries protects them
572470
expect(
573471
cache.read({ query: a, variables: { i: 0 }, optimistic: true }),
574472
).toEqual({ foo: 0 });
575473
expect(
576474
cache.read({ query: a, variables: { i: 1 }, optimistic: true }),
577475
).toEqual({ foo: 1 });
578-
// other partition untouched
579476
expect(
580-
cache.read({ query: b, variables: { i: 0 }, optimistic: true }),
581-
).toEqual({ bar: 0 });
477+
cache.read({ query: a, variables: { i: 2 }, optimistic: true }),
478+
).toEqual({ foo: 2 });
582479
});
583480
});

0 commit comments

Comments
 (0)