Distributed State Locking
Distributed state locking prevents race conditions and ledger corruption when multiple developers or continuous integration pipelines execute testform apply concurrently.
How Locking Works
Section titled “How Locking Works”- Acquisition Attempt: Prior to executing any mutating command (
apply,destroy), Testform registers a unique lock record:ID: Random UUID v4.Operation: Active operation type (e.g.,OperationTypeApply).Who: Hostname and operating system user.Created: UTC timestamp.
- Atomic Write: The configured backend checks if an existing lock exists. If present, execution halts immediately with an error.
- Safe Release: When application completes (whether successful or aborted gracefully), the lock is released.
Handling Lock Failures
Section titled “Handling Lock Failures”If another process is currently applying changes, Testform halts with clear diagnostic details:
Error acquiring state lock: State locked by another process.
Lock Details: ID: e92c1404-9fb6-455c-b452-f4705574581c Path: production/testform.state Operation: OperationTypeApply Who: github-runner-04@actions-node Created: 2026-10-21 14:15:22 UTC
Testform cannot proceed without risk of state corruption.Wait for the previous operation to complete.Safe Force Unlock (testform force-unlock)
Section titled “Safe Force Unlock (testform force-unlock)”If a CI/CD job is abruptly cancelled by a runner timeout or SIGKILL, the distributed lock may remain orphaned.
To release it after confirming that no job is running:
testform force-unlock e92c1404-9fb6-455c-b452-f4705574581cExpected output:
Verifying lock 'e92c1404-9fb6-455c-b452-f4705574581c'...Lock successfully unlocked. State is now ready for reconciliation.