Skip to content

Cyclic Dependencies

Cyclic dependencies are defined in StepUp as closed loops in the dependency graph. Formally, such a loop is defined as a set of source ➜ sink edges (as introduced under Edges) that can be followed such that one arrives back at the starting point. If you construct cyclic dependencies in a plan.py, an error message is generated.

The stepup.core.api enforces acyclic dependencies in the provenance graph and cannot be introduced accidentally by the user.

Example

Create the following plan.py, which is StepUp’s equivalent of a snake biting its own tail:

#!/usr/bin/env python3
from stepup.core.api import copy

copy("a.txt", "b.txt")
copy("b.txt", "a.txt")

Make the plan executable and give it a try as follows:

chmod +x plan.py
sb -j 1

You will get the following terminal output showing that this plan won’t work.

DIRECTOR │ Listening on /tmp/stepup-########/director (StepUp Core 4.0.0)
 STARTUP │ (Re)initialized boot script
   PHASE │ build
   START │ ./plan.py
    FAIL │ ./plan.py
──────────────────────────────── Failed command ────────────────────────────────
./plan.py  # exit=1
──────────────────────────────── Standard error ────────────────────────────────
Shortened traceback (most recent call last). Set STEPUP_DEBUG=1 for details:
  File "./plan.py", line 5, in <module>
    copy("b.txt", "a.txt")
    ~~~~^^^^^^^^^^^^^^^^^^
stepup.core.exceptions.CyclicError: New relation introduces a cyclic dependency
────────────────────────────────────────────────────────────────────────────────
DIRECTOR │ Ran 1 job(s).
 WARNING │ 1 step(s) failed.
 WARNING │ Scheduler is draining. Not reporting pending steps.
 WARNING │ Skipping file cleanup due to incomplete build
 WARNING │ Check logs: .stepup/fail.log .stepup/warning.log
DIRECTOR │ See you!