Skip to content

Commit

Permalink
Identify pool on init (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewMacmurray authored Nov 14, 2023
1 parent ce090e0 commit ff4467a
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 73 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,9 @@ npm install @andrewmacmurray/elm-concurrent-task

### 2. Add to your Elm app

Your Elm program needs
Your Elm program needs:

- A `ConcurrentTask.Pool` in your `Model` to keep track of each task attempt:
- A single `ConcurrentTask.Pool` in your `Model` to keep track of each task attempt:

```elm
type alias Model =
Expand Down Expand Up @@ -365,6 +365,14 @@ const tasks = {

**NOTE**: for a more complete `localStorage` integration with proper error handling [check out the localstorage example](https://github.com/andrewMacmurray/elm-concurrent-task/blob/ba7c8af4b1afeff138ba839511d4411a0a40bbb1/examples/localstorage-fruit-trees/src/index.ts).

## Re-using ports

Each `send` and `receive` port pair only support **one** `ConcurrentTask.Pool` subscribed at a time.
**Weird** things can happen if you have **two or more** `ConcurrentTask.Pool`s using the same ports at the same time.

Generally this should not be needed, but if you have a use-case, please leave an [issue](https://github.com/andrewMacmurray/elm-concurrent-task/issues).


## Develop Locally

Install Dependencies:
Expand Down
102 changes: 61 additions & 41 deletions runner/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ export * from "./browser";

export interface ElmPorts {
send: {
subscribe: (callback: (defs: TaskDefinition[]) => Promise<void>) => void;
subscribe: (
callback: (defs: TaskDefinition[] | Command) => Promise<void>
) => void;
};
receive: { send: (result: TaskResult[]) => void };
receive: { send: (result: TaskResult[] | PoolId) => void };
}

export type Command = { command: "identify-pool" };

export type PoolId = { poolId: number };

export type Tasks = { [fn: string]: (arg: any) => any };

export interface TaskDefinition {
Expand Down Expand Up @@ -118,49 +124,59 @@ export function register(options: Options): void {
const tasks = createTasks(options);
const subscribe = options.ports.send.subscribe;
const send = options.ports.receive.send;

subscribe(async (defs) => {
const debouncedSend = debounce(send, debounceThreshold(defs));

for (const def of defs) {
if (!tasks[def.function]) {
return debouncedSend({
attemptId: def.attemptId,
taskId: def.taskId,
result: {
error: {
reason: "missing_function",
message: `${def.function} is not registered`,
let poolId = 0;

subscribe(async (payload) => {
if ("command" in payload) {
if (payload.command === "identify-pool") {
send({ poolId });
poolId = cycleInt({ max: 1000 }, poolId);
} else {
throw new Error(`Unrecognised internal command: ${payload}`);
}
} else {
const debouncedSend = debounce(send, debounceThreshold(payload));

for (const def of payload) {
if (!tasks[def.function]) {
return debouncedSend({
attemptId: def.attemptId,
taskId: def.taskId,
result: {
error: {
reason: "missing_function",
message: `${def.function} is not registered`,
},
},
},
});
});
}
}
}

defs.map(async (def) => {
try {
logTaskStart(def, options);
const result = await tasks[def.function]?.(def.args);
logTaskFinish(def, options);
debouncedSend({
attemptId: def.attemptId,
taskId: def.taskId,
result: { value: result },
});
} catch (e) {
debouncedSend({
attemptId: def.attemptId,
taskId: def.taskId,
result: {
error: {
reason: "js_exception",
message: `${e.name}: ${e.message}`,
raw: e,
payload.map(async (def) => {
try {
logTaskStart(def, options);
const result = await tasks[def.function]?.(def.args);
logTaskFinish(def, options);
debouncedSend({
attemptId: def.attemptId,
taskId: def.taskId,
result: { value: result },
});
} catch (e) {
debouncedSend({
attemptId: def.attemptId,
taskId: def.taskId,
result: {
error: {
reason: "js_exception",
message: `${e.name}: ${e.message}`,
raw: e,
},
},
},
});
}
});
});
}
});
}
});
}

Expand Down Expand Up @@ -239,3 +255,7 @@ function prefixWith(prefix: string, tasks: Tasks): Tasks {
Object.entries(tasks).map(([key, fn]) => [`${prefix}${key}`, fn])
);
}

function cycleInt(options: { max: number }, i: number): number {
return i >= options.max ? 0 : i + 1;
}
Loading

0 comments on commit ff4467a

Please sign in to comment.