Skip to content

Official support for rewinding failed orchestrations #731

Description

@cgillum

Problem

There are cases when an orchestrator instance can fail due to a bug, an environment issue, etc. In such cases, the orchestration fails, and the process needs to be manually restarted from scratch. This is not ideal because often times the process involved several complex steps, human interactions, etc., and it's not always practical to rebuild that state.

Proposal

The durable task framework uses an event sourcing model under the hood to manage state. This means that in theory it should be possible to "rewind" back to a previously known good state and restart execution from there. Exposing this as a feature would be a great way to recover failed orchestrations (after the underlying issue has been fixed).

Task RewindTaskOrchestrationAsync(string instanceId, string reason);

Design notes

Rewind should work on failed orchestrations (the design could potentially be extended to terminated and completed orchestrations as well). Internally this API enqueues a message that gets picked up by a worker. When the TaskOrchestrationDispatcher receives the message, it will update the in-memory history to remove the last failure and then replay the orchestration with the updated history.

Note that in order for this to work, the storage backends must be willing to process messages for orchestrations in a failed state. This may not be the case today, in which case an alternate design could be to expose a new method on IOrchestrationService for this functionality. However, this has two problems: 1) it still requires existing backends to make changes to support it, 2) new backends will also be required to implement this new capability explicitly, and 3) it won't be feasible to trigger this from a client operation, since TaskHubClient doesn't have direct access to IOrchestrationService methods.

Prior work

This was done originally for Durable Functions but was never directly exposed to DTFx. Also, the core logic was only implemented for the Azure Storage backend (DurableTask.AzureStorage).

To improve on the prior work, we should do two things:

  1. Expose rewind functionality directly in the DurableTask.Core APIs.
  2. Implement the core functionality in DurableTask.Core in such a way that it can work with any backend store without modification.

Implementation notes

As part of making this a generic feature, we should replace the DurableTask.AzureStorage implementation with a generic implementation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions