How to write a while loop?
A while loop consists of a branch, and a condition task inside this branch, which determines whether one revisits the branch again.
One needs to define the branch with loop=True
, and then make sure that there if one _if
decorator, with a jump back to the branch itself.
We begin from empty repo.
$ tb init
Created repository using module "taskblaster.repository" in "/home/myuser/tmprepo".
Here is the simplest example workflow. Create a following workflow.py
import taskblaster as tb
@tb.workflow
class WhileLoopWorkflow:
number = tb.var()
@tb.branch('entry', loop=True)
@tb.task
def iterate(self):
return tb.node(
'iterate_task',
number=self.Phi(default=self.number, entry=self.iterate),
)
@tb.branch('entry', loop=True)
@tb._if(false='entry')
@tb.task
def converged(self):
return tb.node('converged_task', number=self.iterate)
def workflow(rn):
rn.run_workflow(WhileLoopWorkflow(number=3))
and a following tasks.py
def converged_task(number):
return number < 1
def iterate_task(number):
return number - 1
This is the absolutely simplest example of workflow. The Phi-operator argument default refers to
initialization of the while loop, i.e. on the first iteration, we get the input to the iterate task
from the workflow input self.number
. On the next step, we are coming from entry
-branch,
and thus we will refer to the previous result of the iterate.
We can iterate the workflow few times and observe the results
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: add new 0/0 tree/iterate-001 if: add new 0/1 tree/converged-001 T=None F=entry state info tags worker time folder output ──────── ────────── ─────────── ─────────── ─────────── ───────────────────────────── ──────────────────────── done 0/0 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: have done 0/0 tree/iterate-001 if: have done 1/1 tree/converged-001 T=None F=entry jump: entry entry: add new 2/2 tree/iterate-002 if: add new 1/2 tree/converged-002 T=None F=entry state info tags worker time folder output ──────── ────────── ─────────── ─────────── ─────────── ───────────────────────────── ──────────────────────── done 0/0 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False done 2/2 N/A-0/1 00:00:00 tree/iterate-002 1 done 2/2 N/A-0/1 00:00:00 tree/converged-002 False
$ tb workflow workflow.py && tb run . >/dev/null && tb ls --sort=topo -c sirITfo entry: have done 0/0 tree/iterate-001 if: have done 1/1 tree/converged-001 T=None F=entry jump: entry entry: have done 2/2 tree/iterate-002 if: have done 2/2 tree/converged-002 T=None F=entry jump: entry entry: add new 3/3 tree/iterate-003 if: add new 2/3 tree/converged-003 T=None F=entry state info tags worker time folder output ──────── ────────── ─────────── ─────────── ─────────── ───────────────────────────── ──────────────────────── done 0/0 N/A-0/1 00:00:00 tree/iterate-001 2 done 1/1 N/A-0/1 00:00:00 tree/converged-001 False done 2/2 N/A-0/1 00:00:00 tree/iterate-002 1 done 2/2 N/A-0/1 00:00:00 tree/converged-002 False done 3/3 N/A-0/1 00:00:00 tree/iterate-003 0 done 3/3 N/A-0/1 00:00:00 tree/converged-003 True
To view an experimental automatically generated workflow diagram of the workflow here, click here
.
This structure is the simplest for loop. However, to make the initialization and finalization of while loop more clear, and usable, see How to write a practical while loop How to.