scheduler¶
- class Scheduler(nodes: 'dict[str, NodeSpecification]', edges: 'list[Edge]', source_nodes: 'list[NodeID]' = <factory>, event_maker: 'EventMaker' = <factory>, _logger: 'logging.Logger' = <factory>)[source]¶
- nodes: dict[str, NodeSpecification]¶
- source_nodes: list[Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)]]¶
- event_maker: EventMaker¶
- classmethod from_specification(nodes: dict[str, NodeSpecification], edges: list[Edge]) Self[source]¶
Create an instance of a Scheduler from
NodeSpecificationandEdge
- iter_epoch(epoch: Epoch | None = None) Iterator[list[MetaEvent]][source]¶
Iter batches of ready events from an epoch until it’s completed.
- Parameters:
epoch (
Epoch) – Epoch to iterate over. IfNone, adds an epoch to iterate over.- Raises:
EpochCompletedError if the requested epoch has already been completed –
- iter_ready() Iterator[list[MetaEvent]][source]¶
Iter batches of ready events from all epochs, infinitely, until no more nodes can be run in any epoch.
TODO: document stateful/stateless behavior, need for callers to handle breaks in iteration
- add_epoch(epoch: Epoch | None = None) Epoch[source]¶
Add another epoch with a prepared graph to the scheduler.
- add_subepoch(epoch: Epoch) Epoch[source]¶
Add subepoch!
Creates a topo sorter with all the nodes downstream of the node that created the epoch.
- is_active(epoch: Epoch | None = None) bool[source]¶
Graph remains active while it holds at least one epoch that is active.
- get_ready(epoch: Epoch | None = None) list[MetaEvent][source]¶
Output the set of nodes that are ready across different epochs.
- Parameters:
epoch (
Epoch | None) – if an Epoch, get ready events for that epoch, ifNone, get ready events for all epochs.
- node_is_ready(node: Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)], epoch: Epoch, subepochs: bool = False) bool[source]¶
Check if a single node is ready in a single or any epoch
- Parameters:
node (
NodeID) – the node to checkepoch (
int | None) – the epoch to checksubepochs (
bool) – IfTrue, returnTrueif ready in any subepoch too
- node_is_done(node: Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)], epoch: Epoch) bool[source]¶
Node is expired or done in specified epoch
- sources_finished(epoch: Epoch) bool[source]¶
Check the source nodes of the given epoch have been processed. If epoch is None, check the source nodes of the latest epoch.
- update(events: MutableSequence[Event | MetaEvent] | MutableSequence[Event]) MutableSequence[Event] | MutableSequence[Event | MetaEvent][source]¶
When a set of events are received, update the graphs within the scheduler. Currently only has
TopoSorter.done()implemented.
- done(epoch: Epoch, node_id: str, signal: Annotated[str, AfterValidator(func=_is_identifier)] | None = None, with_signals: bool = True) list[MetaEvent][source]¶
Mark a node in a given epoch as done.
- Parameters:
with_signals (
bool) – When marking this node as done, also mark all its signals as done.
- expire(epoch: Epoch, node_id: str, signal: Annotated[str, AfterValidator(func=_is_identifier)] | None = None, with_signals: bool = True, unlock_optionals: bool = True) list[MetaEvent][source]¶
Mark a node as having been completed without making its dependent nodes ready. i.e. when the node emitted
NoEvent
- epoch_completed(epoch: Epoch) bool[source]¶
Check if the epoch has been completed - as in it is fully completed and should no longer be acted upon. Distinct from is_active, which is used to check if an epoch should be marked as complete
- enable_node(node_id: str) None[source]¶
Enable edges attached to the node and the NodeSpecification enable switches to True. Enabling a node clears any existing epochs, so it should only be done between process calls.
- disable_node(node_id: str) None[source]¶
Disable edges attached to the node and the NodeSpecification enable switches to False
- generations() list[list[Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)]]][source]¶
Get the topological generations of the graph: tuples for each set of nodes that can be run at the same time.
Order within a generation is not guaranteed to be stable.
- asset_generations() dict[Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)], list[tuple[str, ...]]][source]¶
generations()except only including nodes with direct dependencies on assets, to determine when the asset should be initialized vs. received in the ZMQ Runner.Packed in a dictionary with the asset ID as the key, and the value as the generations for that asset.
- upstream_nodes(node: Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)]) set[Annotated[str, AfterValidator(func=_is_identifier), AfterValidator(func=_not_reserved)]][source]¶
All the nodes that have an effect on the given node
From: * Dependencies * If the node has optional dependencies, nodes whose NoEvents it should listen to
- get_epoch_state(epoch: Epoch) SorterState[source]¶