Skip to content

Commit

Permalink
[REFACTOR]: Spawn Call
Browse files Browse the repository at this point in the history
  • Loading branch information
amadolid committed Dec 9, 2024
1 parent 2d998f6 commit fbf0666
Show file tree
Hide file tree
Showing 10 changed files with 387 additions and 117 deletions.
10 changes: 5 additions & 5 deletions jac-cloud/jac_cloud/core/architype.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ def update(self, bulk_write: BulkWrite, propagate: bool = False) -> None:
############################################################
# POPULATE ADDED EDGES #
############################################################
added_edges: set[BaseAnchor | Anchor] = (
added_edges: set[BaseAnchor] = (
changes.get("$addToSet", {}).get("edges", {}).get("$each", [])
)
if added_edges:
Expand All @@ -575,7 +575,7 @@ def update(self, bulk_write: BulkWrite, propagate: bool = False) -> None:
############################################################
# POPULATE REMOVED EDGES #
############################################################
pulled_edges: set[BaseAnchor | Anchor] = (
pulled_edges: set[BaseAnchor] = (
changes.get("$pull", {}).get("edges", {}).get("$in", [])
)
if pulled_edges:
Expand Down Expand Up @@ -828,10 +828,10 @@ class WalkerAnchor(BaseAnchor, _WalkerAnchor): # type: ignore[misc]
"""Walker Anchor."""

architype: "WalkerArchitype"
path: list[Anchor] = field(default_factory=list)
next: list[Anchor] = field(default_factory=list)
path: list[NodeAnchor] = field(default_factory=list) # type: ignore[assignment]
next: list[NodeAnchor] = field(default_factory=list) # type: ignore[assignment]
returns: list[Any] = field(default_factory=list)
ignores: list[Anchor] = field(default_factory=list)
ignores: list[NodeAnchor] = field(default_factory=list) # type: ignore[assignment]
disengaged: bool = False

class Collection(BaseCollection["WalkerAnchor"]):
Expand Down
111 changes: 66 additions & 45 deletions jac-cloud/jac_cloud/plugin/jaseci.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
)
from jaclang.plugin.feature import JacFeature as Jac
from jaclang.runtimelib.architype import Architype, DSFunc
from jaclang.runtimelib.utils import all_issubclass

from orjson import loads

Expand Down Expand Up @@ -794,65 +795,85 @@ def spawn_call(op1: Architype, op2: Architype) -> WalkerArchitype:
walker.path = []
walker.next = [node]
walker.returns = []
current_node = node.architype

# walker entry
for i in warch._jac_entry_funcs_:
if i.func and not i.trigger:
walker.returns.append(i.func(warch, current_node))
if walker.disengaged:
return warch

if walker.next:
current_node = walker.next[-1].architype
for i in warch._jac_entry_funcs_:
trigger = i.get_funcparam_annotations(i.func)
if not trigger:
if i.func:
walker.returns.append(i.func(warch, current_node))
else:
raise ValueError(f"No function {i.name} to call.")
while len(walker.next):
if current_node := walker.next.pop(0).architype:
# walker entry with
for i in warch._jac_entry_funcs_:
if (
i.func
and i.trigger
and all_issubclass(i.trigger, NodeArchitype)
and isinstance(current_node, i.trigger)
):
walker.returns.append(i.func(warch, current_node))
if walker.disengaged:
return warch

# node entry
for i in current_node._jac_entry_funcs_:
trigger = i.get_funcparam_annotations(i.func)
if not trigger or isinstance(warch, trigger):
if i.func:
walker.returns.append(i.func(current_node, warch))
else:
raise ValueError(f"No function {i.name} to call.")
if i.func and not i.trigger:
walker.returns.append(i.func(current_node, warch))
if walker.disengaged:
return warch
for i in warch._jac_entry_funcs_:
trigger = i.get_funcparam_annotations(i.func)
if not trigger or isinstance(current_node, trigger):
if i.func and trigger:
walker.returns.append(i.func(warch, current_node))
elif not trigger:
continue
else:
raise ValueError(f"No function {i.name} to call.")

# node entry with
for i in current_node._jac_entry_funcs_:
if (
i.func
and i.trigger
and all_issubclass(i.trigger, WalkerArchitype)
and isinstance(warch, i.trigger)
):
walker.returns.append(i.func(current_node, warch))
if walker.disengaged:
return warch
for i in warch._jac_exit_funcs_:
trigger = i.get_funcparam_annotations(i.func)
if not trigger or isinstance(current_node, trigger):
if i.func and trigger:
walker.returns.append(i.func(warch, current_node))
elif not trigger:
continue
else:
raise ValueError(f"No function {i.name} to call.")

# node exit with
for i in current_node._jac_exit_funcs_:
if (
i.func
and i.trigger
and all_issubclass(i.trigger, WalkerArchitype)
and isinstance(warch, i.trigger)
):
walker.returns.append(i.func(current_node, warch))
if walker.disengaged:
return warch

# node exit
for i in current_node._jac_exit_funcs_:
trigger = i.get_funcparam_annotations(i.func)
if not trigger or isinstance(warch, trigger):
if i.func:
walker.returns.append(i.func(current_node, warch))
else:
raise ValueError(f"No function {i.name} to call.")
if i.func and not i.trigger:
walker.returns.append(i.func(current_node, warch))
if walker.disengaged:
return warch

# walker exit with
for i in warch._jac_exit_funcs_:
if (
i.func
and i.trigger
and all_issubclass(i.trigger, NodeArchitype)
and isinstance(current_node, i.trigger)
):
walker.returns.append(i.func(warch, current_node))
if walker.disengaged:
return warch
# walker exit
for i in warch._jac_exit_funcs_:
trigger = i.get_funcparam_annotations(i.func)
if not trigger:
if i.func:
walker.returns.append(i.func(warch, current_node))
else:
raise ValueError(f"No function {i.name} to call.")
if i.func and not i.trigger:
walker.returns.append(i.func(warch, current_node))
if walker.disengaged:
return warch

walker.ignores = []
return warch

Expand Down
49 changes: 49 additions & 0 deletions jac-cloud/jac_cloud/tests/openapi_specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4109,4 +4109,53 @@ paths:
summary: /visit_nested_node/{node}
tags:
- walker
- walker
/walker/visit_sequence:
post:
operationId: api_root_walker_visit_sequence_post
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Root Walker Visit Sequence Post
description: Successful Response
summary: /visit_sequence
tags:
- walker
- walker
/walker/visit_sequence/{node}:
post:
operationId: api_entry_walker_visit_sequence__node__post
parameters:
- in: path
name: node
required: true
schema:
anyOf:
- type: string
- type: 'null'
title: Node
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Entry Walker Visit Sequence Node Post
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: /visit_sequence/{node}
tags:
- walker
- walker
54 changes: 54 additions & 0 deletions jac-cloud/jac_cloud/tests/simple_graph.jac
Original file line number Diff line number Diff line change
Expand Up @@ -803,4 +803,58 @@ walker delete_custom_object {
# The only difference is BaseAnchor.ref doesn't
# load the actual object and just use it as reference
}
}

##################################################################
# FOR SPAWN CALL SEQUENCE #
##################################################################

node Node {
has val: str;

can entry1 with entry {
return f"{self.val}-2";
}

can entry3 with visit_sequence entry {
return f"{self.val}-3";
}

can exit1 with visit_sequence exit {
return f"{self.val}-4";
}

can exit2 with exit {
return f"{self.val}-5";
}
}

walker visit_sequence {
can entry1 with entry {
return "walker entry";
}

can entry2 with `root entry {
here ++> Node(val = "a");
here ++> Node(val = "b");
here ++> Node(val = "c");
visit [-->];
return "walker enter to root";
}

can entry3 with Node entry {
return f"{here.val}-1";
}

can exit1 with Node exit {
return f"{here.val}-6";
}

can exit2 with exit {
return "walker exit";
}

class __specs__ {
has auth: bool = False;
}
}
46 changes: 42 additions & 4 deletions jac-cloud/jac_cloud/tests/test_simple_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,19 +560,19 @@ def trigger_upload_file(self) -> None:
"single": {
"name": "simple_graph.jac",
"content_type": "application/octet-stream",
"size": 17658,
"size": 18748,
}
},
"multiple": [
{
"name": "simple_graph.jac",
"content_type": "application/octet-stream",
"size": 17658,
"size": 18748,
},
{
"name": "simple_graph.jac",
"content_type": "application/octet-stream",
"size": 17658,
"size": 18748,
},
],
"singleOptional": None,
Expand Down Expand Up @@ -761,6 +761,38 @@ def trigger_delete_custom_object_test(self, obj_id: str) -> None:
self.assertEqual(200, res["status"])
self.assertIsNone(obj)

def trigger_visit_sequence(self) -> None:
"""Test visit sequence."""
res = self.post_api("visit_sequence")

self.assertEqual(200, res["status"])
self.assertEqual(
[
"walker entry",
"walker enter to root",
"a-1",
"a-2",
"a-3",
"a-4",
"a-5",
"a-6",
"b-1",
"b-2",
"b-3",
"b-4",
"b-5",
"b-6",
"c-1",
"c-2",
"c-3",
"c-4",
"c-5",
"c-6",
"walker exit",
],
res["returns"],
)

def test_all_features(self) -> None:
"""Test Full Features."""
self.trigger_openapi_specs_test()
Expand Down Expand Up @@ -864,10 +896,16 @@ def test_all_features(self) -> None:

self.trigger_memory_sync()

##################################################
###################################################
# SAVABLE OBJECT #
###################################################

obj_id = self.trigger_create_custom_object_test()
self.trigger_update_custom_object_test(obj_id)
self.trigger_delete_custom_object_test(obj_id)

###################################################
# VISIT SEQUENCE #
###################################################

self.trigger_visit_sequence()
Loading

0 comments on commit fbf0666

Please sign in to comment.