Const
import { makeEffectDurableExecutor } from 'durable-execution'
import { Schema } from 'effect'
const main = Effect.fn(() => Effect.gen(function* () {
const executor = yield* makeEffectDurableExecutor(storage)
// Create tasks
const extractFileTitle = yield* executor
.inputSchema(Schema.Struct({ filePath: Schema.String }))
.task({
id: 'extractFileTitle',
timeoutMs: 30_000, // 30 seconds
run: async (ctx, input) => {
// ... extract the file title
return {
title: 'File Title',
}
},
})
const summarizeFile = yield* executor
.validateInput(async (input: { filePath: string }) => {
// Example validation function - implement your own validation logic
if (!isValidFilePath(input.filePath)) {
throw new Error('Invalid file path')
}
return {
filePath: input.filePath,
}
})
.task({
id: 'summarizeFile',
timeoutMs: 30_000, // 30 seconds
run: async (ctx, input) => {
// ... summarize the file
return {
summary: 'File summary',
}
},
})
const uploadFile = yield* executor
.inputSchema(Schema.Struct({ filePath: Schema.String, uploadUrl: Schema.String }))
.parentTask({
id: 'uploadFile',
timeoutMs: 60_000, // 1 minute
runParent: async (ctx, input) => {
// ... upload file to the given uploadUrl
// Extract the file title and summarize the file in parallel
return {
output: {
filePath: input.filePath,
uploadUrl: input.uploadUrl,
fileSize: 100,
},
children: [
childTask(extractFileTitle, { filePath: input.filePath }),
childTask(summarizeFile, { filePath: input.filePath }),
],
}
},
finalize: {
id: 'uploadFileFinalize',
timeoutMs: 60_000, // 1 minute
run: async (ctx, { output, children }) => {
// ... combine the output of the run function and children tasks
return {
filePath: output.filePath,
uploadUrl: output.uploadUrl,
fileSize: 100,
title: 'File Title',
summary: 'File summary',
}
}
},
})
// Start the durable executor
yield* executor.start()
// Enqueue task and manage its execution lifecycle
const uploadFileHandle = yield* executor.enqueueTask(uploadFile, {
filePath: 'file.txt',
uploadUrl: 'https://example.com/upload',
})
const uploadFileExecution = yield* uploadFileHandle.getExecution()
const uploadFileFinishedExecution = yield* uploadFileHandle.waitAndGetFinishedExecution()
yield* uploadFileHandle.cancel()
yield* Effect.log(uploadFileExecution)
}).pipe(Effect.scoped)
Make an effect durable executor. It is used to execute tasks durably, reliably and resiliently.
Multiple durable executors can share the same storage. In such a case, all the tasks should be present for all the durable executors. The work is distributed among the durable executors. See the usage and task examples sections for more details on creating and enqueuing tasks.
It provides the same functionality as DurableExecutor but operates within the effect ecosystem, returning effect values instead of promises.
Key Differences from DurableExecutor