Skip to content

Commit

Permalink
[Serving] Verify that functions referenced in steps are added as chil…
Browse files Browse the repository at this point in the history
…dren (#1866)
  • Loading branch information
yaronha committed Apr 7, 2022
1 parent ff00fb4 commit 14cfc8a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
13 changes: 12 additions & 1 deletion mlrun/runtimes/serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ def _deploy_function_refs(self):
function_object.metadata.labels[
"mlrun/parent-function"
] = self.metadata.name
function_object._is_child_function = True
if not function_object.spec.graph:
# copy the current graph only if the child doesnt have a graph of his own
function_object.set_env("SERVING_CURRENT_FUNCTION", function_ref.name)
Expand Down Expand Up @@ -537,10 +538,20 @@ def deploy(
if not self.spec.graph:
raise ValueError("nothing to deploy, .spec.graph is none, use .add_model()")

if self.spec.graph.kind != StepKinds.router:
if self.spec.graph.kind != StepKinds.router and not getattr(
self, "_is_child_function", None
):
# initialize or create required streams/queues
self.spec.graph.check_and_process_graph()
self.spec.graph.init_queues()
functions_in_steps = self.spec.graph.list_child_functions()
child_functions = list(self._spec.function_refs.keys())
for function in functions_in_steps:
if function not in child_functions:
raise mlrun.errors.MLRunInvalidArgumentError(
f"function {function} is used in steps and is not defined, "
"use the .add_child_function() to specify child function attributes"
)

# Handle secret processing before handling child functions, since secrets are transferred to them
if self.spec.secret_sources:
Expand Down
8 changes: 8 additions & 0 deletions mlrun/serving/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,14 @@ def init_queues(self):
if step.kind == StepKinds.queue:
step.init_object(self.context, None)

def list_child_functions(self):
"""return a list of child function names referred to in the steps"""
functions = []
for step in self.get_children():
if step.function and step.function not in functions:
functions.append(step.function)
return functions

def is_empty(self):
"""is the graph empty (no child steps)"""
return len(self.steps) == 0
Expand Down
12 changes: 12 additions & 0 deletions tests/serving/test_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,15 @@ def check_function(name, fn):
"new_function",
mlrun.new_function("test2", command=function_path, kind="serving"),
)


def test_missing_functions():
function = mlrun.new_function("tests", kind="serving")
graph = function.set_topology("flow", engine="async")
graph.to(name="s1", class_name="Echo").to(
name="s2", class_name="Echo", function="child_func"
)
with pytest.raises(
mlrun.errors.MLRunInvalidArgumentError, match=r"function child_func*"
):
function.deploy()

0 comments on commit 14cfc8a

Please sign in to comment.