Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

format with prettier #2

Merged
merged 3 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
name: Run tests
on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
cache-dependency-path: |
example/package-lock.json
package-lock.json
node-version: '18.x'
cache: 'npm'
- run: npm i
- run: npm ci
- run: cd example && npm i && cd ..
- run: npm test
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
- run: npm i
- run: npm ci
- run: cd example && npm i && cd ..
- run: npm test
3 changes: 3 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"trailingComma": "es5"
}
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ const scrapePool = new Workpool(components.scrapeWorkpool, {
export const signUp = mutation({
handler: async (ctx, args) => {
const userId = await ctx.db.insert("users", args);
await emailPool.enqueueAction(internal.auth.sendEmailVerification, { userId });
await emailPool.enqueueAction(internal.auth.sendEmailVerification, {
userId,
});
},
});

Expand Down
1 change: 0 additions & 1 deletion example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@

Components need an app that uses them in order to run codegen. An example app is also useful
for testing and documentation.

2 changes: 1 addition & 1 deletion example/convex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function handleButtonPress() {
// OR
// use the result once the mutation has completed
mutation({ first: "Hello!", second: "me" }).then((result) =>
console.log(result),
console.log(result)
);
}
```
Expand Down
13 changes: 5 additions & 8 deletions example/convex/example.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
/// <reference types="vite/client" />

import { convexTest } from "convex-test";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import schema from "./schema";
import componentSchema from "../../src/component/schema";
import cronsSchema from "../../node_modules/@convex-dev/crons/src/component/schema";
import { api, components } from "./_generated/api";

const modules = import.meta.glob("./**/*.ts");
const componentModules = import.meta.glob("../../src/component/**/*.ts");
const cronsModules = import.meta.glob("../../node_modules/@convex-dev/crons/src/component/**/*.ts");
const cronsModules = import.meta.glob(
"../../node_modules/@convex-dev/crons/src/component/**/*.ts"
);

describe("workpool", () => {
async function setupTest() {
Expand Down Expand Up @@ -47,16 +49,11 @@ describe("workpool", () => {
});

test("enqueue and get status", async () => {
const id = await t.mutation(api.example.enqueueOneMutation, {data: 1});
const id = await t.mutation(api.example.enqueueOneMutation, { data: 1 });
await runToCompletion();
expect(await t.query(api.example.status, { id })).toEqual({
kind: "success",
result: 1,
});
})

test("drop in replacement for ctx", async () => {
const result = await t.action(api.example.doSomethingInPool, {});
expect(result).toEqual(3);
});
});
18 changes: 9 additions & 9 deletions example/convex/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { api, components } from "./_generated/api";
import { WorkId, WorkPool } from "@convex-dev/workpool";
import { v } from "convex/values";

const pool = new WorkPool(components.workpool, {
const pool = new WorkPool(components.workpool, {
maxParallelism: 3,
// For tests, disable completed work cleanup.
completedWorkMaxAgeMs: Number.POSITIVE_INFINITY,
Expand All @@ -20,20 +20,20 @@ export const addMutation = mutation({
args: { data: v.optional(v.number()) },
handler: async (ctx, { data }) => {
const d = data ?? Math.random();
await ctx.db.insert("data", {data: d});
await ctx.db.insert("data", { data: d });
return d;
},
});

export const addAction = action({
args: { data: v.optional(v.number()) },
handler: async (ctx, { data }): Promise<number> => {
return await ctx.runMutation(api.example.addMutation, {data});
return await ctx.runMutation(api.example.addMutation, { data });
},
});

export const enqueueOneMutation = mutation({
args: {data: v.number()},
args: { data: v.number() },
handler: async (ctx, { data }): Promise<string> => {
return await pool.enqueueMutation(ctx, api.example.addMutation, { data });
},
Expand All @@ -43,7 +43,7 @@ export const status = query({
args: { id: v.string() },
handler: async (ctx, { id }) => {
return await pool.status(ctx, id as WorkId<null>);
}
},
});

export const enqueueABunchOfMutations = mutation({
Expand All @@ -59,7 +59,7 @@ export const addLowPri = mutation({
args: { data: v.optional(v.number()) },
handler: async (ctx, { data }) => {
const d = -(data ?? Math.random());
await ctx.db.insert("data", {data: d});
await ctx.db.insert("data", { data: d });
return d;
},
});
Expand All @@ -86,7 +86,7 @@ export const enqueueAndWait = action({
args: {},
handler: async (ctx, _args): Promise<number> => {
const work = await pool.enqueueAction(ctx, api.example.addAction, {});
const result = await pool.pollResult(ctx, work, 30*1000);
const result = await pool.pollResult(ctx, work, 30 * 1000);
return result;
},
});
Expand All @@ -101,7 +101,7 @@ export const doSomethingInPool = action({
});

async function doSomething(ctx: ActionCtx): Promise<number> {
const data1 = await ctx.runMutation(api.example.addMutation, {data: 1});
const data2 = await ctx.runAction(api.example.addAction, {data: 2});
const data1 = await ctx.runMutation(api.example.addMutation, { data: 1 });
const data2 = await ctx.runAction(api.example.addAction, { data: 2 });
return data1 + data2;
}
12 changes: 5 additions & 7 deletions example/convex/schema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema(
{
data: defineTable({
data: v.number(),
}),
},
);
export default defineSchema({
data: defineTable({
data: v.number(),
}),
});
6 changes: 3 additions & 3 deletions node10stubs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ async function processSubPackages(packageJsonPath, exports, cleanup = false) {
await fs.mkdir(newDir, { recursive: true });
await fs.writeFile(
newPackageJsonPath,
JSON.stringify(newPackageJson, null, 2),
JSON.stringify(newPackageJson, null, 2)
);
}
}
Expand All @@ -71,11 +71,11 @@ async function main() {

if (isCleanup) {
console.log(
"Node10 module resolution compatibility stub directories removed.",
"Node10 module resolution compatibility stub directories removed."
);
} else {
console.log(
"Node10 module resolution compatibility stub directories created",
"Node10 module resolution compatibility stub directories created"
);
}
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"prepack": "node node10stubs.mjs",
"postpack": "node node10stubs.mjs --cleanup",
"test": "vitest run",
"format": "prettier --write .",
"test:debug": "vitest --inspect-brk --no-file-parallelism",
"test:coverage": "vitest run --coverage --coverage.reporter=text"
},
Expand Down Expand Up @@ -64,7 +65,7 @@
"devDependencies": {
"@eslint/js": "^9.9.1",
"@types/node": "^18.17.0",
"convex-test": "file:../convex-test/convex-test-0.0.33.tgz",
"convex-test": "^0.0.35-alpha.0",
"eslint": "^9.9.1",
"globals": "^15.9.0",
"prettier": "3.2.5",
Expand Down
56 changes: 32 additions & 24 deletions src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,45 @@ export class WorkPool {
private options: {
// How many actions/mutations can be running at once within this pool.
// Min 1, Max 300.
maxParallelism: number,
maxParallelism: number;
// How long an action can run before the pool considers it to be timed out.
// The action itself might time out earlier.
// Default 15 minutes.
actionTimeoutMs?: number,
actionTimeoutMs?: number;
// How long a mutation can run before the pool considers it to be timed out.
// The mutation itself might time out earlier.
// Default 30 seconds.
mutationTimeoutMs?: number,
mutationTimeoutMs?: number;
// How long a function started by `enqueueUnknown` or `runAt` or `runAfter`
// can run before the pool considers it to be timed out.
// The function itself might time out earlier.
// Default 15 minutes.
unknownTimeoutMs?: number,
unknownTimeoutMs?: number;
// When there is something to do, wait this long between loop iterations,
// to allow more work to accumulate.
// Default 50ms.
debounceMs?: number,
debounceMs?: number;
// When something is running, wait this long to check if anything has
// been canceled or failed unexpectedly.
// Default 10s.
fastHeartbeatMs?: number,
fastHeartbeatMs?: number;
// When nothing is happening, wait this long to check if there is new work
// that we missed.
// Default 2 hours.
slowHeartbeatMs?: number,
slowHeartbeatMs?: number;
// How much to log.
// Default WARN.
logLevel?: LogLevel,
logLevel?: LogLevel;
// How long to keep completed work in the database, for access by `status`,
// `tryResult`, and `pollResult`.
// Default 1 day.
completedWorkMaxAgeMs?: number,
completedWorkMaxAgeMs?: number;
}
) {}
async enqueueAction<Args extends DefaultFunctionArgs, ReturnType>(
ctx: RunMutationCtx,
fn: FunctionReference<'action', FunctionVisibility, Args, ReturnType>,
fnArgs: Args,
fn: FunctionReference<"action", FunctionVisibility, Args, ReturnType>,
fnArgs: Args
): Promise<WorkId<ReturnType>> {
const handle = await createFunctionHandle(fn);
const id = await ctx.runMutation(this.component.public.enqueue, {
Expand All @@ -74,8 +74,8 @@ export class WorkPool {
}
async enqueueMutation<Args extends DefaultFunctionArgs, ReturnType>(
ctx: RunMutationCtx,
fn: FunctionReference<'mutation', FunctionVisibility, Args, ReturnType>,
fnArgs: Args,
fn: FunctionReference<"mutation", FunctionVisibility, Args, ReturnType>,
fnArgs: Args
): Promise<WorkId<ReturnType>> {
const handle = await createFunctionHandle(fn);
const id = await ctx.runMutation(this.component.public.enqueue, {
Expand All @@ -91,16 +91,21 @@ export class WorkPool {
// which can happen if it comes from `runAt` or `runAfter`.
async enqueueUnknown<Args extends DefaultFunctionArgs>(
ctx: RunMutationCtx,
fn: FunctionReference<'action' | 'mutation', FunctionVisibility, Args, null>,
fn: FunctionReference<
"action" | "mutation",
FunctionVisibility,
Args,
null
>,
fnArgs: Args,
runAtTime: number,
runAtTime: number
): Promise<WorkId<null>> {
const handle = await createFunctionHandle(fn);
const id = await ctx.runMutation(this.component.public.enqueue, {
handle,
options: this.options,
fnArgs,
fnType: 'unknown',
fnType: "unknown",
runAtTime,
});
return id as WorkId<null>;
Expand All @@ -110,15 +115,18 @@ export class WorkPool {
}
async status<ReturnType>(
ctx: RunQueryCtx,
id: WorkId<ReturnType>,
id: WorkId<ReturnType>
): Promise<
{ kind: "pending" } | { kind: "inProgress" } | { kind: "success", result: ReturnType } | { kind: "error", error: string }
| { kind: "pending" }
| { kind: "inProgress" }
| { kind: "success"; result: ReturnType }
| { kind: "error"; error: string }
> {
return await ctx.runQuery(this.component.public.status, { id });
}
async tryResult<ReturnType>(
ctx: RunQueryCtx,
id: WorkId<ReturnType>,
id: WorkId<ReturnType>
): Promise<ReturnType | undefined> {
const status = await this.status(ctx, id);
if (status.kind === "success") {
Expand All @@ -132,7 +140,7 @@ export class WorkPool {
async pollResult<ReturnType>(
ctx: RunQueryCtx & RunActionCtx,
id: WorkId<ReturnType>,
timeoutMs: number,
timeoutMs: number
): Promise<ReturnType> {
const start = Date.now();
while (true) {
Expand All @@ -147,16 +155,16 @@ export class WorkPool {
}
}
ctx<DataModel extends GenericDataModel>(
ctx: GenericActionCtx<DataModel>,
ctx: GenericActionCtx<DataModel>
): GenericActionCtx<DataModel> {
return {
runAction: (async (action: any, args: any) => {
const workId = await this.enqueueAction(ctx, action, args);
return this.pollResult(ctx, workId, 30*1000);
return this.pollResult(ctx, workId, 30 * 1000);
}) as any,
runMutation: (async (mutation: any, args: any) => {
const workId = await this.enqueueMutation(ctx, mutation, args);
return this.pollResult(ctx, workId, 30*1000);
return this.pollResult(ctx, workId, 30 * 1000);
}) as any,
scheduler: {
runAfter: async (delay: number, fn: any, args: any) => {
Expand All @@ -167,7 +175,7 @@ export class WorkPool {
},
cancel: async (id: any) => {
await this.cancel(ctx, id);
}
},
} as any,
auth: ctx.auth,
storage: ctx.storage,
Expand Down
2 changes: 1 addition & 1 deletion src/component/convex.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ const component = defineComponent("workpool");

component.use(crons);

export default component;
export default component;
2 changes: 1 addition & 1 deletion src/component/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const logLevel = v.union(
v.literal("DEBUG"),
v.literal("INFO"),
v.literal("WARN"),
v.literal("ERROR"),
v.literal("ERROR")
);
export type LogLevel = Infer<typeof logLevel>;

Expand Down
Loading