dhiaayachi / temporal

Temporal service
https://docs.temporal.io
MIT License
0 stars 0 forks source link

is fastflow support rollback? #365

Open dhiaayachi opened 1 month ago

dhiaayachi commented 1 month ago

in my case, i want to use temporal to create some resources on a public cloud. like creating a cloud vm with public ip.

  1. create a vm using cloud openapi
  2. wait the status of vm is running(may cost some minutes)
  3. create a public ip using cloud openapi
  4. wait the status of public ip is available(may cost some seconds)
  5. bind the public ip with vm
  6. other steps

i want

  1. if one step failed, workflow can free the created resources(vm,public ip etc) automaticlly. temporal is ok.
  2. if I cancel the workflow(like run flow.cancel()), can temporal free the created resources(vm,public ip etc) ?
dhiaayachi commented 1 month ago

Thank you for your feature request.

Temporal currently does not have a built-in way to automatically clean up resources when a workflow fails or is canceled. However, you can implement this logic in your workflow using a combination of activity and signals.

Here's how:

  1. Create a cleanup activity: This activity would be responsible for freeing any created resources like the VM and public IP.
  2. Use signals to trigger cleanup: When the workflow fails or is canceled, it can send a signal to itself to trigger the cleanup activity.
  3. Handle the signal in your workflow: Your workflow would listen for the cleanup signal and execute the cleanup activity when it receives it.

You can also use the Workflow.Cancel or Workflow.Terminate API in the Temporal SDK to cancel or terminate a running workflow execution and invoke cleanup activities. Refer to Cancellation and Interrupt a Workflow for more details.

dhiaayachi commented 1 month ago

Thank you for the feature request!

Temporal doesn't currently have automatic cleanup of resources in the case of a workflow failure or cancellation. However, you can achieve this by using a finally block in your workflow or activities, which always executes regardless of whether the step succeeded or failed, and then invoke a cleanup activity to free resources.

Example of the finally block:

from temporalio import workflow, activity

@workflow.defn
class MyWorkflow:
  @workflow.run
  async def run(self) -> None:
    try:
      vm_id = await self.create_vm()
      await self.wait_vm_running(vm_id)
      public_ip = await self.create_public_ip()
      await self.wait_public_ip_available(public_ip)
      await self.bind_public_ip(vm_id, public_ip)
    except Exception:
      await self.cleanup(vm_id, public_ip)
      raise
    finally:
      await self.cleanup(vm_id, public_ip)

@activity.defn
async def create_vm():
    # Implement vm creation logic
    # ...

@activity.defn
async def wait_vm_running(vm_id):
    # Implement vm status wait logic
    # ...

@activity.defn
async def create_public_ip():
    # Implement public ip creation logic
    # ...

@activity.defn
async def wait_public_ip_available(public_ip):
    # Implement public ip status wait logic
    # ...

@activity.defn
async def bind_public_ip(vm_id, public_ip):
    # Implement binding logic
    # ...

@activity.defn
async def cleanup(vm_id, public_ip):
    # Implement cleanup logic
    # ...

In this example, if any step fails, the cleanup activity is called to free the created resources. This activity is also called in the finally block, which ensures the cleanup happens even if the workflow is canceled. You can extend this pattern to handle other cleanup steps within the workflow.

dhiaayachi commented 1 month ago

Thank you for reaching out!

This is a great feature request. Temporal does not currently have the ability to automatically clean up resources when a workflow fails or is canceled. However, you can use a workaround to achieve similar functionality.

Workaround:

  1. Create a cleanup activity: Implement an activity that frees the created resources (VM, public IP, etc.).
  2. Call cleanup activity on failure or cancellation: In your workflow, call the cleanup activity within a finally block or a catch block for any exception that indicates a failure. You can also use a Signal to trigger cleanup.

Example:

// Workflow Definition
async function createAndBindResource() {
  try {
    await createVm();
    await waitForVmRunning();
    await createPublicIp();
    await waitForPublicIpAvailable();
    await bindPublicIpToVm();
    // Other steps
  } catch (error) {
    // Call cleanup activity on failure
    await cleanupResources();
  } finally {
    // Call cleanup activity regardless of success or failure
    await cleanupResources();
  }
}

// Cleanup activity
async function cleanupResources() {
  await deleteVm();
  await deletePublicIp();
  // Other cleanup steps
}

Let me know if you have any other questions.