Fields
Fields are how loops are created in a workflow graph.
Fields are defined by a Field Transmitter and a Field Receiver. Any nodes between these will be part of the Field and will be iterated until either the Transmitter runs out of data or the Receiver decides its conditions are met.
To mark a Transmitter or Reciever as a Feild, set is_field=True
on the attribute decorator.
@wob.transmitter("value", "name", is_field=True)
def transmit_values(self):
...
@wob.receiver("value", "name", is_field=True)
def receiver_values(self):
...
A Field Transmitter is expected to return a tuple of two iterators. The first iterator is used as “peek ahead” to determine if there is more data available. The second iterator is the actual data. An easy way to do this is to use the tee
function from the itertools
module to turn an array into two iterators.
Here’s an example of a node that splits a string by commas and returns the strings as a Field.
from mirmod.controls import Textbox
import itertools
@wob.init()
def init(self):
self.values = None
self.iterator = None
@wob.receiver("value","input", control=Textbox(placeholder="a,b,c,..."))
def receive_input(self, i):
self.values = i.split(',')
@wob.transmitter("value", "output", is_field=True)
def transmit_values(self):
return self.iterator
@wob.execute()
def execute(self):
self.iterator = itertools.tee(self.values)
These values can then be collected using the miranda.collector
Prefab.
This pattern will output the following:
== Collector ==
++ input_2:
['a', 'b', 'c']
++ output_2: a b c
Writing a Field Receiver is similar to writing a normal Receiver, it will just be called multiple times until the Transmitter runs out of data. Here’s an example of a node that prints each value in a Field.
@wob.receiver("value", "input", is_field=True)
def receive_values(self, i):
print(i)
After all values have been received, execution will continue like normal. However, the Reciever can also use one of the Execution Context hooks to break out of the loop early. Here’s an example of a node that will only recieve the first two values in a Field, then break back into normal execution.
@wob.receiver("value", "input", is_field=True)
def receive_values(self, i):
print(i)
self.count_received += 1
if self.count_received >= 2:
# Break out of the current Field and continue normal execution
miranda.get_execution_context().stop_current_iterator()