Skip to content

Commit

Permalink
* MS CreateAccessor lets caller choose the "result comparer" for the …
Browse files Browse the repository at this point in the history
…underlying "computed" call. This enables caching for some situations that weren't easily possible before; for more info, see: mobxjs/mobx#2437 (comment)
  • Loading branch information
Venryx committed Sep 24, 2023
1 parent f67bded commit 0299fdd
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 29 deletions.
3 changes: 2 additions & 1 deletion Dist/Accessors/@AccessorCallPlan.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class AccessorCallPlan {
//uselessCachingWarned = false;
//_lastCall_startTime?: number; // for debugging/profiling purposes only
Call_OrReturnCache() {
var _a;
var _a, _b;
// cache hit, return
if (this.cachedResult_wrapper != null) {
return this.cachedResult_wrapper.get();
Expand All @@ -87,6 +87,7 @@ export class AccessorCallPlan {
this.cachedResult_wrapper = computed(() => this.accessorMeta.accessor.apply(this, this.callArgs), {
name: `computedFn(${this.accessorMeta.accessor.name}#${++this.callPlanIndex})`,
keepAlive: (_a = this.accessorMeta.options.cache_keepAlive) !== null && _a !== void 0 ? _a : false,
equals: (_b = this.accessorMeta.options.cache_comparer) !== null && _b !== void 0 ? _b : undefined,
});
// if/when the cached-result-wrapper becomes no-longer-observed, also clean up this call-plan object
if (!this.accessorMeta.options.cache_keepAlive) {
Expand Down
3 changes: 2 additions & 1 deletion Dist/Accessors/@AccessorMetadata.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IComputedValueOptions } from "mobx";
import { IComputedValueOptions, IEqualsComparer } from "mobx";
import { Graphlink } from "../index.js";
import { UT_StoreShape } from "../UserTypes.js";
import { BailError } from "../Utils/General/BailManager.js";
Expand All @@ -8,6 +8,7 @@ export declare class AccessorOptions<RootState = any, DBShape = any> {
static default: AccessorOptions<any, any>;
graph?: Graphlink<RootState, DBShape>;
cache: boolean;
cache_comparer?: IEqualsComparer<any>;
cache_keepAlive: boolean;
cache_unwrapArrays: boolean;
}
Expand Down
2 changes: 1 addition & 1 deletion Dist/Accessors/Helpers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export declare type AddEffect = (effectFunc: EffectFunc) => void;
/** Similar to GetAsync, except includes helper for delaying effect-execution (ie. mobx changes) till end, and without certain data-centric behaviors (like disabling db-cache during resolution). */
export declare function WaitTillResolvedThenExecuteSideEffects({ resolveCondition, effectExecution, timeout, onTimeout, timeoutMessage, }: {
resolveCondition?: "returns true" | "no bail-error" | "no error" | undefined;
effectExecution?: "plain" | "action" | undefined;
effectExecution?: "action" | "plain" | undefined;
timeout?: number | n;
onTimeout?: "resolve promise" | "reject promise" | "do nothing" | undefined;
timeoutMessage?: string | undefined;
Expand Down
3 changes: 2 additions & 1 deletion Source/Accessors/@AccessorCallPlan.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {IsPrimitive} from "js-vextensions";
import {computed, IComputedValue, IComputedValueOptions, onBecomeUnobserved, _isComputingDerivation} from "mobx";
import {comparer, computed, IComputedValue, IComputedValueOptions, onBecomeUnobserved, _isComputingDerivation} from "mobx";
import {Graphlink, CatchBail} from "../index.js";
import {UT_StoreShape} from "../UserTypes.js";
import {AccessorMetadata, ProfilingInfo} from "./@AccessorMetadata.js";
Expand Down Expand Up @@ -122,6 +122,7 @@ export class AccessorCallPlan {
this.cachedResult_wrapper = computed(()=>this.accessorMeta.accessor.apply(this, this.callArgs), {
name: `computedFn(${this.accessorMeta.accessor.name}#${++this.callPlanIndex})`,
keepAlive: this.accessorMeta.options.cache_keepAlive ?? false,
equals: this.accessorMeta.options.cache_comparer ?? undefined,
});
// if/when the cached-result-wrapper becomes no-longer-observed, also clean up this call-plan object
if (!this.accessorMeta.options.cache_keepAlive) {
Expand Down
3 changes: 2 additions & 1 deletion Source/Accessors/@AccessorMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {CE} from "js-vextensions";
import {IComputedValue, IComputedValueOptions, computed, onBecomeUnobserved, _isComputingDerivation, onBecomeObserved} from "mobx"
import {IComputedValue, IComputedValueOptions, computed, onBecomeUnobserved, _isComputingDerivation, onBecomeObserved, comparer, IEqualsComparer} from "mobx"
import {Graphlink} from "../index.js";
import {UT_StoreShape} from "../UserTypes.js";
import {BailError} from "../Utils/General/BailManager.js";
Expand All @@ -19,6 +19,7 @@ export class AccessorOptions<RootState = any, DBShape = any> {
//graph: Graphlink<any, any>;

cache = true;
cache_comparer?: IEqualsComparer<any>;
cache_keepAlive = false;
cache_unwrapArrays = true;
//callArgToDependencyConvertorFunc?: CallArgToDependencyConvertorFunc;
Expand Down
46 changes: 22 additions & 24 deletions Source/Components/DataCommitScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,34 +48,32 @@ export class DataCommitScheduler {
// wrapping multiple commit-funcs in a single action is a nice idea, but the time-based throttling system doesn't really work then, since almost all the execution time is in running the reactions
// we leave it like this for now though, opting instead to rely on the "dataUpdateBuffering_commitSetMaxFuncCount" option
RunInAction("DataCommitScheduler.commit", ()=>{

const commitStartTime = Date.now();
let commitFuncsExecuted = 0;
while (commitFuncsLeftToRun.length > 0) {
const func = commitFuncsLeftToRun.shift()!;
func();
//RunInAction("DataCommitScheduler.commit", ()=>func());
commitFuncsExecuted++;
if (commitFuncsExecuted >= this.graph.options.dataUpdateBuffering_commitSetMaxFuncCount) {
break;
}
if (Date.now() - commitStartTime > this.graph.options.dataUpdateBuffering_commitSetMaxTime) {
break;
const commitStartTime = Date.now();
let commitFuncsExecuted = 0;
while (commitFuncsLeftToRun.length > 0) {
const func = commitFuncsLeftToRun.shift()!;
func();
//RunInAction("DataCommitScheduler.commit", ()=>func());
commitFuncsExecuted++;
if (commitFuncsExecuted >= this.graph.options.dataUpdateBuffering_commitSetMaxFuncCount) {
break;
}
if (Date.now() - commitStartTime > this.graph.options.dataUpdateBuffering_commitSetMaxTime) {
break;
}
}
}

// if we haven't run all the commit-funcs yet, schedule the next subset to run in a moment
if (commitFuncsLeftToRun.length > 0) {
setTimeout(ProceedWithCommitting, this.graph.options.dataUpdateBuffering_breakDuration);
} else {
this.scheduledCommit_status = "inactive";
// if we haven't run all the commit-funcs yet, schedule the next subset to run in a moment
if (commitFuncsLeftToRun.length > 0) {
setTimeout(ProceedWithCommitting, this.graph.options.dataUpdateBuffering_breakDuration);
} else {
this.scheduledCommit_status = "inactive";

// there were commit-funcs that wanted in on this set, but had to wait; kick off a new set for them
if (this.scheduledCommit_commitFuncs.length > 0) {
this.ScheduleDataUpdateCommit(()=>{});
// there were commit-funcs that wanted in on this set, but had to wait; kick off a new set for them
if (this.scheduledCommit_commitFuncs.length > 0) {
this.ScheduleDataUpdateCommit(()=>{});
}
}
}

});
};
ProceedWithCommitting();
Expand Down

0 comments on commit 0299fdd

Please sign in to comment.