Skip to content
Open
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
28 changes: 28 additions & 0 deletions src/cloudflare/internal/test/workflows/workflows-api-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,34 @@ export const workflowsApi = {
assert.deepStrictEqual(instances[1].id, 'bar');
}

{
const result = await env.workflow.createBatch({
count: 2,
params: { bar: 'baz' },
});
assert.deepStrictEqual(
result.created.map(({ id }) => id),
['generated-0', 'generated-1']
);
assert.deepStrictEqual(result.errors, []);
}

{
const result = await env.workflow.createBatch({
instances: [{ id: 'batch-ok' }, { id: 'batch-error' }],
});
assert.deepStrictEqual(result.created[0].id, 'batch-ok');
assert.strictEqual(typeof result.created[0].status, 'function');
assert.deepStrictEqual(result.errors, [
{
index: 1,
id: 'batch-error',
code: 10405,
message: 'Provided instance ID already exists',
},
]);
}

{
const result = await env.workflow.deleteBatch([
'delete-1',
Expand Down
28 changes: 27 additions & 1 deletion src/cloudflare/internal/test/workflows/workflows-mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const restartBodies = new Map();
const subscribeOptions = new Map();

const THROW_ID = 'throw';
const BATCH_ERROR_ID = 'batch-error';
const MISSING_DELETE_ID = 'missing-delete';

class SubscriptionMock extends RpcTarget {
Expand Down Expand Up @@ -41,7 +42,32 @@ export default class WorkflowsMock extends WorkerEntrypoint {
}

async createBatch(options) {
return options.map((val) => ({ id: val.id }));
if (Array.isArray(options)) {
return options.map((val) => ({ id: val.id }));
}

const instances =
options.instances ??
Array.from({ length: options.count }, (_, index) => ({
id: `generated-${index}`,
}));
const created = [];
const errors = [];

for (const [index, instance] of instances.entries()) {
if (instance.id === BATCH_ERROR_ID) {
errors.push({
index,
id: instance.id,
code: 10405,
message: 'Provided instance ID already exists',
});
} else {
created.push({ id: instance.id });
}
}

return { created, errors };
}

async deleteBatch(options) {
Expand Down
31 changes: 27 additions & 4 deletions src/cloudflare/internal/workflows-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ interface Fetcher {
createBatch(
options: WorkflowInstanceCreateOptions[]
): Promise<{ id: string }[]>;
createBatch(options: WorkflowBatchCreateOptions): Promise<{
created: { id: string }[];
errors: WorkflowBatchCreateResult['errors'];
}>;
deleteBatch(options: {
instances: string[];
}): Promise<WorkflowBatchDeleteResult>;
Expand Down Expand Up @@ -123,10 +127,29 @@ class WorkflowImpl extends wrappedBinding.WrappedBinding {

async createBatch(
options: WorkflowInstanceCreateOptions[]
): Promise<WorkflowInstance[]> {
const results = await this.#fetcher.createBatch(options);

return results.map((result) => new InstanceImpl(result.id, this.#fetcher));
): Promise<WorkflowInstance[]>;
async createBatch(
options: WorkflowBatchCreateOptions
): Promise<WorkflowBatchCreateResult>;
async createBatch(
options: WorkflowInstanceCreateOptions[] | WorkflowBatchCreateOptions
): Promise<WorkflowInstance[] | WorkflowBatchCreateResult> {
if (Array.isArray(options)) {
const results = await this.#fetcher.createBatch(options);

return results.map(
(result) => new InstanceImpl(result.id, this.#fetcher)
);
}

const result = await this.#fetcher.createBatch(options);

return {
created: result.created.map(
({ id }) => new InstanceImpl(id, this.#fetcher)
),
errors: result.errors,
};
}

async deleteBatch(instanceIds: string[]): Promise<WorkflowBatchDeleteResult> {
Expand Down
43 changes: 40 additions & 3 deletions src/cloudflare/internal/workflows.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,53 @@ declare abstract class Workflow<PARAMS = unknown> {
): Promise<WorkflowInstance>;

/**
* Create a batch of instances and return handle for all of them. If a provided id exists, an error will be thrown.
* Create a batch of instances and return handles for the created instances and any per-instance errors.
* `createBatch` is limited at 100 instances at a time or when the RPC limit (1MiB) is reached.
* @param batch List of Options when creating an instance including name and params
* @returns A promise that resolves with a list of handles for the created instances.
* @param options Options for creating instances by count or from a list of instance options
* @returns A promise that resolves with the created instance handles and any per-instance errors.
*/
createBatch(
options: WorkflowBatchCreateOptions<PARAMS>
): Promise<WorkflowBatchCreateResult>;

/**
* Create a batch of instances and return handles for all of them.
* @deprecated Use the object form of `createBatch` instead of the array form.
*/
createBatch(
batch: WorkflowInstanceCreateOptions<PARAMS>[]
): Promise<WorkflowInstance[]>;
}

type WorkflowBatchCreateOptions<PARAMS = unknown> =
| {
count: number;
params?: PARAMS;
retention?: {
successRetention?: WorkflowRetentionDuration;
errorRetention?: WorkflowRetentionDuration;
};
locationHint?: WorkflowInstanceLocationHint;
instances?: never;
}
| {
instances: WorkflowInstanceCreateOptions<PARAMS>[];
count?: never;
params?: never;
retention?: never;
locationHint?: never;
};

type WorkflowBatchCreateResult = {
created: WorkflowInstance[];
errors: {
index: number;
id?: string;
code: number;
message: string;
}[];
};

type WorkflowDurationLabel =
'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';

Expand Down
43 changes: 40 additions & 3 deletions types/defines/workflows.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@ declare abstract class Workflow<PARAMS = unknown> {
): Promise<WorkflowInstance>;

/**
* Create a batch of instances and return handle for all of them. If a provided id exists, an error will be thrown.
* Create a batch of instances and return handles for the created instances and any per-instance errors.
* `createBatch` is limited at 100 instances at a time or when the RPC limit for the batch (1MiB) is reached.
* @param batch List of Options when creating an instance including name and params
* @returns A promise that resolves with a list of handles for the created instances.
* @param options Options for creating instances by count or from a list of instance options
* @returns A promise that resolves with the created instance handles and any per-instance errors.
*/
public createBatch(
options: WorkflowBatchCreateOptions<PARAMS>
): Promise<WorkflowBatchCreateResult>;

/**
* Create a batch of instances and return handles for all of them.
* @deprecated Use the object form of `createBatch` instead of the array form.
*/
public createBatch(
batch: WorkflowInstanceCreateOptions<PARAMS>[]
Expand All @@ -45,6 +53,35 @@ declare abstract class Workflow<PARAMS = unknown> {
public deleteBatch(instanceIds: string[]): Promise<WorkflowBatchDeleteResult>;
}

type WorkflowBatchCreateOptions<PARAMS = unknown> =
| {
count: number;
params?: PARAMS;
retention?: {
successRetention?: WorkflowRetentionDuration;
errorRetention?: WorkflowRetentionDuration;
};
locationHint?: WorkflowInstanceLocationHint;
instances?: never;
}
| {
instances: WorkflowInstanceCreateOptions<PARAMS>[];
count?: never;
params?: never;
retention?: never;
locationHint?: never;
};

type WorkflowBatchCreateResult = {
created: WorkflowInstance[];
errors: {
index: number;
id?: string;
code: number;
message: string;
}[];
};

type WorkflowBatchDeleteResult = {
deleted: { id: string }[];
errors: {
Expand Down
40 changes: 37 additions & 3 deletions types/generated-snapshot/experimental/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17667,10 +17667,17 @@ declare abstract class Workflow<PARAMS = unknown> {
options?: WorkflowInstanceCreateOptions<PARAMS>,
): Promise<WorkflowInstance>;
/**
* Create a batch of instances and return handle for all of them. If a provided id exists, an error will be thrown.
* Create a batch of instances and return handles for the created instances and any per-instance errors.
* `createBatch` is limited at 100 instances at a time or when the RPC limit for the batch (1MiB) is reached.
* @param batch List of Options when creating an instance including name and params
* @returns A promise that resolves with a list of handles for the created instances.
* @param options Options for creating instances by count or from a list of instance options
* @returns A promise that resolves with the created instance handles and any per-instance errors.
*/
public createBatch(
options: WorkflowBatchCreateOptions<PARAMS>,
): Promise<WorkflowBatchCreateResult>;
/**
* Create a batch of instances and return handles for all of them.
* @deprecated Use the object form of `createBatch` instead of the array form.
*/
public createBatch(
batch: WorkflowInstanceCreateOptions<PARAMS>[],
Expand All @@ -17684,6 +17691,33 @@ declare abstract class Workflow<PARAMS = unknown> {
*/
public deleteBatch(instanceIds: string[]): Promise<WorkflowBatchDeleteResult>;
}
type WorkflowBatchCreateOptions<PARAMS = unknown> =
| {
count: number;
params?: PARAMS;
retention?: {
successRetention?: WorkflowRetentionDuration;
errorRetention?: WorkflowRetentionDuration;
};
locationHint?: WorkflowInstanceLocationHint;
instances?: never;
}
| {
instances: WorkflowInstanceCreateOptions<PARAMS>[];
count?: never;
params?: never;
retention?: never;
locationHint?: never;
};
type WorkflowBatchCreateResult = {
created: WorkflowInstance[];
errors: {
index: number;
id?: string;
code: number;
message: string;
}[];
};
type WorkflowBatchDeleteResult = {
deleted: {
id: string;
Expand Down
40 changes: 37 additions & 3 deletions types/generated-snapshot/experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17616,10 +17616,17 @@ export declare abstract class Workflow<PARAMS = unknown> {
options?: WorkflowInstanceCreateOptions<PARAMS>,
): Promise<WorkflowInstance>;
/**
* Create a batch of instances and return handle for all of them. If a provided id exists, an error will be thrown.
* Create a batch of instances and return handles for the created instances and any per-instance errors.
* `createBatch` is limited at 100 instances at a time or when the RPC limit for the batch (1MiB) is reached.
* @param batch List of Options when creating an instance including name and params
* @returns A promise that resolves with a list of handles for the created instances.
* @param options Options for creating instances by count or from a list of instance options
* @returns A promise that resolves with the created instance handles and any per-instance errors.
*/
public createBatch(
options: WorkflowBatchCreateOptions<PARAMS>,
): Promise<WorkflowBatchCreateResult>;
/**
* Create a batch of instances and return handles for all of them.
* @deprecated Use the object form of `createBatch` instead of the array form.
*/
public createBatch(
batch: WorkflowInstanceCreateOptions<PARAMS>[],
Expand All @@ -17633,6 +17640,33 @@ export declare abstract class Workflow<PARAMS = unknown> {
*/
public deleteBatch(instanceIds: string[]): Promise<WorkflowBatchDeleteResult>;
}
export type WorkflowBatchCreateOptions<PARAMS = unknown> =
| {
count: number;
params?: PARAMS;
retention?: {
successRetention?: WorkflowRetentionDuration;
errorRetention?: WorkflowRetentionDuration;
};
locationHint?: WorkflowInstanceLocationHint;
instances?: never;
}
| {
instances: WorkflowInstanceCreateOptions<PARAMS>[];
count?: never;
params?: never;
retention?: never;
locationHint?: never;
};
export type WorkflowBatchCreateResult = {
created: WorkflowInstance[];
errors: {
index: number;
id?: string;
code: number;
message: string;
}[];
};
export type WorkflowBatchDeleteResult = {
deleted: {
id: string;
Expand Down
Loading
Loading