Locks and Leases

Use a durable <lock> when two workflow runs must not change the same resource at once. WOML keeps a FIFO wait queue, renews the current lease, and issues a larger fencing token when ownership changes. Waiting releases the script worker.

Protect a multi-step operation

Place the lock inside <steps> after the step that identifies the resource:

WOML
<lock id="deployment" key="production/{{context.steps.plan.service}}" acquire-timeout="15m" lease="45s">
  <step id="deploy">
    <script>
      return {
        service: context.steps.plan.service,
        fencingToken: context.lock.fencingToken
      };
    </script>
  </step>
  <step id="verify">
    <script>return { healthy: true };</script>
  </step>
</lock>

Runs with the same key are serialized; different keys can proceed independently. Do not put secrets or raw payloads in a lock key. Pass the fencing token to an external system that supports fencing: a lease alone cannot stop an old process from writing after it loses ownership.

Choose the right scope

For one short critical section within a script, use services.locks.withLease(). Its callback is not a durable JavaScript closure. Use markup <lock> for several steps, restart recovery, or a wait or approval inside the protected scope.

Cancellation, timeout, failure, and restart preserve the durable ownership rules. Inspect a run before operating on a stuck resource:

Terminal
woml get <run-id>