mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Introduce a way to run many synchronous runnables
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
497c5258e6
commit
d4b2ff992a
155
src/main/start-main-application/run-many-sync-for.test.ts
Normal file
155
src/main/start-main-application/run-many-sync-for.test.ts
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import {
|
||||
createContainer,
|
||||
getInjectable,
|
||||
getInjectionToken,
|
||||
} from "@ogre-tools/injectable";
|
||||
|
||||
import type { RunnableSync } from "./run-many-sync-for";
|
||||
import { runManySyncFor } from "./run-many-sync-for";
|
||||
|
||||
describe("runManySyncFor", () => {
|
||||
describe("given hierarchy, when running many", () => {
|
||||
let runMock: jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
const rootDi = createContainer();
|
||||
|
||||
runMock = jest.fn();
|
||||
|
||||
const someInjectionTokenForRunnables = getInjectionToken<RunnableSync>({
|
||||
id: "some-injection-token",
|
||||
});
|
||||
|
||||
const someInjectable = getInjectable({
|
||||
id: "some-injectable",
|
||||
instantiate: () => ({ run: runMock }),
|
||||
injectionToken: someInjectionTokenForRunnables,
|
||||
});
|
||||
|
||||
const someOtherInjectable = getInjectable({
|
||||
id: "some-other-injectable",
|
||||
instantiate: () => ({ run: runMock }),
|
||||
injectionToken: someInjectionTokenForRunnables,
|
||||
});
|
||||
|
||||
rootDi.register(someInjectable, someOtherInjectable);
|
||||
|
||||
const runMany = runManySyncFor(rootDi)(someInjectionTokenForRunnables);
|
||||
|
||||
runMany();
|
||||
});
|
||||
|
||||
it("runs all runnables at the same time", () => {
|
||||
expect(runMock).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("given hierarchy that is three levels deep, when running many", () => {
|
||||
let runMock: jest.Mock<(arg: string) => void>;
|
||||
|
||||
beforeEach(() => {
|
||||
const di = createContainer();
|
||||
|
||||
runMock = jest.fn();
|
||||
|
||||
const someInjectionTokenForRunnables = getInjectionToken<RunnableSync>({
|
||||
id: "some-injection-token",
|
||||
});
|
||||
|
||||
const someInjectable1 = getInjectable({
|
||||
id: "some-injectable-1",
|
||||
|
||||
instantiate: (di) => ({
|
||||
run: () => runMock("third-level-run"),
|
||||
runAfter: di.inject(someInjectable2),
|
||||
}),
|
||||
|
||||
injectionToken: someInjectionTokenForRunnables,
|
||||
});
|
||||
|
||||
const someInjectable2 = getInjectable({
|
||||
id: "some-injectable-2",
|
||||
|
||||
instantiate: (di) => ({
|
||||
run: () => runMock("second-level-run"),
|
||||
runAfter: di.inject(someInjectable3),
|
||||
}),
|
||||
|
||||
injectionToken: someInjectionTokenForRunnables,
|
||||
});
|
||||
|
||||
const someInjectable3 = getInjectable({
|
||||
id: "some-injectable-3",
|
||||
instantiate: () => ({ run: () => runMock("first-level-run") }),
|
||||
injectionToken: someInjectionTokenForRunnables,
|
||||
});
|
||||
|
||||
di.register(someInjectable1, someInjectable2, someInjectable3);
|
||||
|
||||
const runMany = runManySyncFor(di)(someInjectionTokenForRunnables);
|
||||
|
||||
runMany();
|
||||
});
|
||||
|
||||
it("runs runnables in order", () => {
|
||||
expect(runMock.mock.calls).toEqual([["first-level-run"], ["second-level-run"], ["third-level-run"]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when running many with parameter", () => {
|
||||
let runMock: jest.Mock<(arg: string, arg2: string) => void>;
|
||||
|
||||
beforeEach(() => {
|
||||
const rootDi = createContainer();
|
||||
|
||||
runMock = jest.fn();
|
||||
|
||||
const someInjectionTokenForRunnablesWithParameter = getInjectionToken<
|
||||
RunnableSync<string>
|
||||
>({
|
||||
id: "some-injection-token",
|
||||
});
|
||||
|
||||
const someInjectable = getInjectable({
|
||||
id: "some-runnable-1",
|
||||
|
||||
instantiate: () => ({
|
||||
run: (parameter) => runMock("run-of-some-runnable-1", parameter),
|
||||
}),
|
||||
|
||||
injectionToken: someInjectionTokenForRunnablesWithParameter,
|
||||
});
|
||||
|
||||
const someOtherInjectable = getInjectable({
|
||||
id: "some-runnable-2",
|
||||
|
||||
instantiate: () => ({
|
||||
run: (parameter) => runMock("run-of-some-runnable-2", parameter),
|
||||
}),
|
||||
|
||||
injectionToken: someInjectionTokenForRunnablesWithParameter,
|
||||
});
|
||||
|
||||
rootDi.register(someInjectable, someOtherInjectable);
|
||||
|
||||
const runMany = runManySyncFor(rootDi)(
|
||||
someInjectionTokenForRunnablesWithParameter,
|
||||
);
|
||||
|
||||
runMany("some-parameter");
|
||||
});
|
||||
|
||||
it("runs all runnables using the parameter", () => {
|
||||
expect(runMock.mock.calls).toEqual([
|
||||
["run-of-some-runnable-1", "some-parameter"],
|
||||
["run-of-some-runnable-2", "some-parameter"],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
39
src/main/start-main-application/run-many-sync-for.ts
Normal file
39
src/main/start-main-application/run-many-sync-for.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import type {
|
||||
DiContainerForInjection,
|
||||
InjectionToken,
|
||||
} from "@ogre-tools/injectable";
|
||||
import { filter, map } from "lodash/fp";
|
||||
|
||||
export interface RunnableSync<TParameter = void> {
|
||||
run: (parameter: TParameter) => void;
|
||||
runAfter?: this;
|
||||
}
|
||||
|
||||
export const runManySyncFor =
|
||||
(di: DiContainerForInjection) =>
|
||||
<TRunnable extends RunnableSync<unknown>>(
|
||||
injectionToken: InjectionToken<TRunnable, void>,
|
||||
) =>
|
||||
(parameter: Parameters<TRunnable["run"]>[0]) => {
|
||||
const allRunnables = di.injectMany(injectionToken);
|
||||
|
||||
const recursedRun = (runAfterRunnable: RunnableSync<unknown> = undefined) =>
|
||||
pipeline(
|
||||
allRunnables,
|
||||
|
||||
filter((runnable) => runnable.runAfter === runAfterRunnable),
|
||||
|
||||
map((runnable) => {
|
||||
runnable.run(parameter);
|
||||
|
||||
recursedRun(runnable);
|
||||
}),
|
||||
);
|
||||
|
||||
recursedRun();
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user