Question
When I start 1000+ Workflows in quick succession it results in ~0-4 ContextDeadlineExceeded failures per 1k workflows creation attempts. What can I tune to stop this from occurring? What are the best practices for launching huge bursts of workflows?
Background
There’s a few instances where I want to create 10,000+ new workflows at once.
Attempted Remedies
I’ve tried to add a 10 minute connection timeout to the WorkflowClient. Unclear if it had any effect as the ContextDeadlineExceeded errors still occur, will probably bump it to 30 minutes just in case.
import { Connection, WorkflowClient } from "@temporalio/client";
let workflowDaddy: any = Connection.connect( { connectTimeout:600000 } )
.then( (connection) => { workflowDaddy = new WorkflowClient({connection}); } ).catch(console.error);
Also switched from attempting to start them all in parallel to starting them all in series. This added a lot of extra execution time but still didn’t stop ContextDeadlineExceeded
// Start workflows all at once
let promises = []
for(entry of manyThings){
promises.push(
workflowDaddy.start(someWorkflow, {
args: [entry],
taskQueue: "workflows",
workflowId:"[someWorkflow]~" + entry.id
}))
}
await Promise.allSettled(promises)
// Start workflows one at a time
for(entry of manyThings){
await workflowDaddy.start(someWorkflow, {
args: [entry],
taskQueue: "workflows",
workflowId:"[someWorkflow]~" + entry.id
})
}
Example Error + Trace
ServiceError: Failed to start Workflow
at WorkflowClient.rethrowGrpcError (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/workflow-client.ts:606:13)
at WorkflowClient._startWorkflowHandler (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/workflow-client.ts:756:12)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async WorkflowClient.start (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/workflow-client.ts:417:19)
at async Activity.nftFinesseFlows [as fn] (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/src/temporal/shared-activities.ts:89:4)
at async Activity.execute (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/worker/src/activity.ts:64:12)
at async ActivityInboundLogInterceptor.execute (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/worker/src/activity-log-interceptor.ts:38:14)
at async /mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/worker/src/activity.ts:71:24
at async /mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/worker/src/worker.ts:906:26 {
cause: Error: 4 DEADLINE_EXCEEDED: context deadline exceeded
at Object.callErrorFromStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/call.ts:81:17)
at Object.onReceiveStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/client.ts:352:36)
at /mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/call-stream.ts:206:27
at onReceiveStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/grpc-retry.ts:176:17)
at Object.onReceiveStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/grpc-retry.ts:180:13)
at InterceptingListenerImpl.onReceiveStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/call-stream.ts:202:19)
at Object.onReceiveStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/client-interceptors.ts:462:34)
at Object.onReceiveStatus (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/client-interceptors.ts:424:48)
at /mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/call-stream.ts:330:24
at processTicksAndRejections (node:internal/process/task_queues:78:11)
for call at
at ServiceClientImpl.makeUnaryRequest (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@grpc/grpc-js/src/client.ts:324:26)
at Service.rpcImpl (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/connection.ts:340:21)
at Service.rpcCall (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/protobufjs/src/rpc/service.js:94:21)
at executor (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@protobufjs/aspromise/index.js:44:16)
at new Promise (<anonymous>)
at Object.asPromise (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@protobufjs/aspromise/index.js:28:12)
at Service.rpcCall (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/protobufjs/src/rpc/service.js:86:21)
at Service.startWorkflowExecution (eval at Codegen (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@protobufjs/codegen/index.js:50:33), <anonymous>:4:15)
at WorkflowClient._startWorkflowHandler (/mnt/SSD/Sorcery/Pulsr/pulsr-temporal/node_modules/@temporalio/client/src/workflow-client.ts:746:46)
at runMicrotasks (<anonymous>) {
code: 4,
details: 'context deadline exceeded',
metadata: Metadata { internalRepr: [Map], options: {} }
}
}