enabling aggressive cacheing with delta mode?
In delta mode, RxQ will parse the delta response, apply the patch, and then pass on the completed value to the receiver of the value. This happens even if the delta patch is an empty array, meaning no changes to the last seen value.
This means that anything listening for a layout for example will get the exact same layout again. When building an app that relies on the layout, like say a component in a React app, this means that the component will unnecessarily re-render with the same layout as before.
It would be beneficial if there was a way for the component to know that it's value actually didn't change to prevent unnecessary renders.
One option:
- Create a session level aggressive cacheing flag. This would change the logic in delta mode such that if the delta was an empty array, it wouldn't emit a value again at all. The downside of this approach is that if you have two separate Observables making the same API call, one of them could potentially never receive a value. For example, imagine two observables that get the engine version:
const engineVersion1 = global$.pipe(qAsk("EngineVersion"));
const engineVersion2 = global$.pipe(qAsk("EngineVersion"));
engineVersion1$.subscribe(console.log);
engineVersion2$.subscribe(console.log);
In this example, the first subscriber would get the value since the delta response would set the engine version. However, the second subscriber's delta response would be an empty array with no changes since the previous API call from the first Observable already got the response. Therefore, it would not receive any value with aggressive cacheing on.
So to use aggressive cacheing like this at the session level, a developer would have to be extremely careful that any API that is made comes only from 1 Observable that can keep history for all of its subscribers. The minute you have different places in the app making the same API call, you run the risk of dropping responses.
Second option:
- for any response from the Engine that is an object, add a
lastPatchDateproperty that lets us know when the value was actually updated by the delta patcher. That way, developers could write logic to only get distinctly patched values like so:
// Assume a normal layouts stream
const layouts$;
// Aggressive cacheing of the layout stream
const distinctLayouts$ = layouts$.pipe(
distinctUntilKeyChanged("lastPatchDate")
);
This seems like a reasonable compromise, but would it mess up our types if we wrote them for RxQ eventually? Or could this be easily accomplished with optional properties on the Engine types? That would mean our types wouldn't be 1 to 1 with the Engine though, since we'd be adding a special property specific to RxQ. @sunpar what do you think?
@sunpar maybe this could be accomplished by extending types? https://stackoverflow.com/questions/41385059/possible-to-extend-types-in-typescript
So you'd have something like
type QLayout {
// layout props...
}
// either
interface DeltaLayout extends QLayout {
lastPatchDate: string;
}
// or
type DeltaLayout = QLayout & { lastPatchDate: string }