About tasks
Tasks are durable units of work that can be scheduled and executed by the Taskurai system. Each task has a unique identifier and can contain various arguments and configurations. Tasks can be created, updated, and monitored through the Taskurai API.
Tasks execute a command that is running in a worker. Task initialization data, configuration, intermediate and final results are persisted in Taskurai.
Tasks can also be created as part of and existing command, like creating sub tasks, in orchestration workflows.
Task identifier
Each task has an unique task identifier that can be used to reference task data in the system.
Task Order
Tasks are initiated in the order they are created (FIFO). However, several factors may affect this behavior:
- Workers can scale horizontally and support concurrent task processing. This may prevent guaranteed execution order.
- When a worker retrieves a task, the task is hidden for a set duration. If a worker fails to complete a task (for example, due to a crash), the task becomes available again and can be picked up by another worker instance. This can disrupt the task order.
- The number of worker instances is a target rather than a guarantee. Limiting a worker to a single instance doesn't necessarily mean only one instance will be running. For example, during a new deployment, both the old and new instances may run concurrently for a short time.
Delivery Guarantee
Taskurai guarantees task delivery with an At-Least-Once delivery mechanism.
Each worker leases a task for a specified time. You should configure the worker so that the command timeout is appropriate for initial task inspection. Workers can extend the lease multiple times while performing the task. In the event of a worker crash, with a well-configured timeout, another worker instance can quickly take over the task.
Since a task can be processed more than once (due to a crash or timeout), your commands should be idempotent and return deterministic results. A deterministic command always returns the same value given the same input, regardless of when or how often it is executed.
For example, if your command generates an order confirmation PDF, only one file should be created. Each run should produce identical results, and in some cases, it may be sufficient to overwrite the same file.
You can leverage the Durable Steps and Workflows, in combination with State management built into Taskurai to help design for idempotency.
Retry policy
By default, failed tasks are retried according to the default retry policy. Each task can override certain policies by providing a custom retry policy in the task execution options.
Stateful tasks
Tasks are automatically persisted and can recover after a resume or restart.
The following data is persisted:
- Task initialization data;
- Task progress;
- Task output data;
All data that is persisted in a task should be serializable.
Tasks are not designed to store large amounts of data or binary data. Large amounts of data of binary content should be stored in Taskurai's build in state stores or in a storage location of choice. The task initialization and output data can reference data stored in a state store.
Task lifecycle and retry policy
By design, commands can (and will) run multiple times to run orchestrations or handle task and step retries. Code should be designed to be idempotent, meaning that the command can be run multiple times without side effects.
The overal retry-policy is part of the task execution options.
All commands should respect the CancellationToken passed in the context. The cancellation token is used to cancel the step when the task is canceled. The cancellation token should be passed to all async calls and should be used to cancel long running operations. When a step or command fails to stop, then the worker will be marked as unhealthy and will be restarted.
Versioning durable commands
Versioning commands enables you to introduce new logic for new future tasks, without affecting running tasks.
When calling tasks, either explicit versions or version-less commands can be called. In case of a version-less command, the default command is selected.
Handling compensation when a task fails
To use compensation logic, please implement Durable Steps & Workflow in the command.