Name the sizes a node can ask for
Raw cpus and gpus are a property of the machines an installation has, so a node written against a cluster quietly stops meaning anything when the cluster is replaced. A node says "gpu-small" instead, and what that is stored here — editable, and read again every time the node is built, so changing the flavor changes what the next run gets. Memory joins the schema properly (`ram`, in MB, accepting "2G"), along with `duration_s` for how long a node is expected to take. That one is recorded and shown and nothing else yet: a statement for whoever is planning around the node, not a limit — the limit is still `timeout`. A flavor and a number for the same thing is refused, compared by value so an editor writing the whole object back with its defaults still round-trips. A name nothing stores is refused at the save, which covers the canvas and `fluksio sync` at once, and deleting one a node still asks for says which node. Four sizes are seeded on an installation that has none, and never re-seeded: re-adding one somebody deliberately removed is an argument nobody wins. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A6HeySA27EkGANZN95QySW
This commit is contained in:
@@ -64,7 +64,12 @@ from fluksio.flow.pipeline import (
|
||||
)
|
||||
from fluksio.flow.placement import Placer
|
||||
from fluksio.flow.remote import RemoteWorkerHub
|
||||
from fluksio.flow.resources import ResourceAccountant, derive_env
|
||||
from fluksio.flow.resources import (
|
||||
ResourceAccountant,
|
||||
UnknownFlavor,
|
||||
derive_env,
|
||||
resolve_flavor,
|
||||
)
|
||||
from fluksio.flow.schemas import (
|
||||
BrainEdge,
|
||||
BrainGraph,
|
||||
@@ -869,11 +874,10 @@ class FlowController:
|
||||
# Building
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def _runs_elsewhere(self, node_def: NodeDef) -> bool:
|
||||
def _runs_elsewhere(self, wanted: Resources | None) -> bool:
|
||||
"""Whether this node asks for more than this machine could ever give."""
|
||||
if node_def.resources is None or self.placer is None:
|
||||
if wanted is None or self.placer is None:
|
||||
return False
|
||||
wanted = node_def.resources
|
||||
return not self.placer.local.fits(wanted.cpus, wanted.gpus, wanted.ram or 0)
|
||||
|
||||
def _placed(
|
||||
@@ -1016,6 +1020,18 @@ class FlowController:
|
||||
# one importing torch is correct on the GPU box and a
|
||||
# missing module here, so checking it here would fail a
|
||||
# node that is fine.
|
||||
try:
|
||||
# A named size is read now rather than stored on the
|
||||
# node, so editing the flavor edits the next run.
|
||||
wanted = (
|
||||
resolve_flavor(node_def.resources)
|
||||
if node_def.resources is not None
|
||||
else None
|
||||
)
|
||||
except UnknownFlavor as exc:
|
||||
entry.status = NodeStatus.ERROR
|
||||
entry.error = str(exc)
|
||||
return entry
|
||||
remote_only = (
|
||||
node_def.device
|
||||
and node_def.device_policy == "require"
|
||||
@@ -1025,7 +1041,7 @@ class FlowController:
|
||||
problem = self.remote.compile(
|
||||
node_def.device or "", owner, local, code
|
||||
)
|
||||
elif self._runs_elsewhere(node_def):
|
||||
elif self._runs_elsewhere(wanted):
|
||||
# Asks for more than this machine has, so it will run on
|
||||
# one that has it. Same reason as a device: checking the
|
||||
# import here would fail a node that is fine there.
|
||||
@@ -1043,13 +1059,13 @@ class FlowController:
|
||||
if node_def.timeout is not None
|
||||
else settings.FLOW_NODE_TIMEOUT
|
||||
)
|
||||
if node_def.resources is not None and self.placer is not None:
|
||||
if wanted is not None and self.placer is not None:
|
||||
# Says how much of a machine it takes, so which machine
|
||||
# and how much of it are one decision — including when
|
||||
# it also names a device, which used to mean the two
|
||||
# answers disagreed and nothing was accounted at all.
|
||||
function = self._placed(
|
||||
node_def.resources,
|
||||
wanted,
|
||||
node_def.device,
|
||||
node_def.device_policy,
|
||||
owner,
|
||||
|
||||
Reference in New Issue
Block a user