Skip to content

Commit

Permalink
Cache signals returned from connector functions
Browse files Browse the repository at this point in the history
Without caching the created signal from a connector function, a signal is
created on every connect. We don't need that overhead and can reuse
existing signals for the same connectors.
  • Loading branch information
stwa committed May 13, 2019
1 parent b7bafaa commit 14c8231
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/connector.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ import { signalFn } from "./signal";
*/

let registry = new Map();
let signalCache = new Map();

function cacheAndReturn(connectorId, signal) {
// remove freed signals from the cache
signal.onFree(() => signalCache.delete(connectorId));
signalCache.set(connectorId, signal);
return signal;
}

/**
* Returns a function that calls `fn` with a list of values extracted from the
Expand Down Expand Up @@ -46,9 +54,12 @@ export function withInputSignals(inputsFn, fn) {
* `connector`, registering a computation function for `connectorId`.
*/
export function connect(connectorId) {
if (signalCache.has(connectorId)) {
return signalCache.get(connectorId);
}
let connectorFn = registry.get(connectorId);
if (computationFn) {
return computationFn(connectorId);
if (connectorFn) {
return cacheAndReturn(connectorId, connectorFn(connectorId));
}
console.warn("no connector registered for:", connectorId);
}
Expand All @@ -74,6 +85,9 @@ export function connector(connectorId, computationFn) {
* `connectorId` and must return a `signalFn`.
*/
export function rawConnector(connectorId, connectorFn) {
if (signalCache.has(connectorId)) {
signalCache.delete(connectorId);
}
registry.set(connectorId, connectorFn);
return connectorFn;
}
Expand All @@ -83,4 +97,5 @@ export function rawConnector(connectorId, connectorFn) {
*/
export function clearConnectors() {
registry.clear();
signalCache.clear();
}
36 changes: 36 additions & 0 deletions src/connector.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ describe("connect", () => {
"bar",
);
});
it("caches signals from connectors", () => {
connector("foo", () => {});
const s1 = connect("foo");
const s2 = connect("foo");
expect(s1).toBe(s2);
});
it("removes freed signals from cache", () => {
connector("foo", () => {});
const s1 = connect("foo");
s1.free();
const s2 = connect("foo");
expect(s1).not.toBe(s2);
});
});

describe("connector", () => {
Expand All @@ -50,6 +63,13 @@ describe("connector", () => {
});
expect(connect("bar").value()).toBe(true);
});
it("removes cached signals when overwriting", () => {
connector("foo", () => {});
const s1 = connect("foo");
connector("foo", () => {});
const s2 = connect("foo");
expect(s1).not.toBe(s2);
});
});

describe("rawConnector", () => {
Expand All @@ -58,6 +78,13 @@ describe("rawConnector", () => {
rawConnector("foo", () => signal);
expect(connect("foo")).toBe(signal);
});
it("removes cached signals when overwriting", () => {
rawConnector("foo", () => signalFn(() => "foo"));
const s1 = connect("foo");
rawConnector("foo", () => signalFn(() => "foo"));
const s2 = connect("foo");
expect(s1).not.toBe(s2);
});
});

describe("clearConnectors", () => {
Expand All @@ -67,4 +94,13 @@ describe("clearConnectors", () => {
clearConnectors();
expect(connect("foo")).toBeUndefined();
});
it("removes cached signals", () => {
connector("foo", () => {});
const s1 = connect("foo");
clearConnectors();
const s2 = connect("foo");
expect(s1).not.toBe(s2);
expect(s1).toBeTruthy();
expect(s2).toBeFalsy();
});
});

0 comments on commit 14c8231

Please sign in to comment.