fix: Enhance vertex runnability logic with loop detection (#6309)

* feat: add is_loop property to Vertex class for detecting looping outputs

* feat: improve vertex runnability logic for graph traversal

- Update `is_vertex_runnable` to handle loop vertices more robustly
- Modify `are_all_predecessors_fulfilled` to better manage cycle dependencies
- Change adjacency maps to use sets for more efficient predecessor/successor tracking

* refactor: change graph adjacency maps from lists to sets for improved performance

- Update graph data structures to use sets instead of lists for predecessor, successor, and parent-child maps
- Modify type hints and method signatures to reflect the change from list to set
- Improve graph traversal and vertex tracking efficiency by using set operations
This commit is contained in:
Gabriel Luiz Freitas Almeida 2025-02-13 09:02:36 -03:00 committed by GitHub
commit f5a2c1cb3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 88 additions and 41 deletions

View file

@ -90,8 +90,9 @@ def test_is_vertex_runnable(data):
manager = RunnableVerticesManager.from_dict(data)
vertex_id = "A"
is_active = True
is_loop = False
result = manager.is_vertex_runnable(vertex_id, is_active=is_active)
result = manager.is_vertex_runnable(vertex_id, is_active=is_active, is_loop=is_loop)
assert result is False
@ -100,8 +101,9 @@ def test_is_vertex_runnable__wrong_is_active(data):
manager = RunnableVerticesManager.from_dict(data)
vertex_id = "A"
is_active = False
is_loop = False
result = manager.is_vertex_runnable(vertex_id, is_active=is_active)
result = manager.is_vertex_runnable(vertex_id, is_active=is_active, is_loop=is_loop)
assert result is False
@ -110,8 +112,9 @@ def test_is_vertex_runnable__wrong_vertices_to_run(data):
manager = RunnableVerticesManager.from_dict(data)
vertex_id = "D"
is_active = True
is_loop = False
result = manager.is_vertex_runnable(vertex_id, is_active=is_active)
result = manager.is_vertex_runnable(vertex_id, is_active=is_active, is_loop=is_loop)
assert result is False
@ -120,8 +123,9 @@ def test_is_vertex_runnable__wrong_run_predecessors(data):
manager = RunnableVerticesManager.from_dict(data)
vertex_id = "C"
is_active = True
is_loop = False
result = manager.is_vertex_runnable(vertex_id, is_active=is_active)
result = manager.is_vertex_runnable(vertex_id, is_active=is_active, is_loop=is_loop)
assert result is False
@ -129,8 +133,9 @@ def test_is_vertex_runnable__wrong_run_predecessors(data):
def test_are_all_predecessors_fulfilled(data):
manager = RunnableVerticesManager.from_dict(data)
vertex_id = "A"
is_loop = False
result = manager.are_all_predecessors_fulfilled(vertex_id)
result = manager.are_all_predecessors_fulfilled(vertex_id, is_loop=is_loop)
assert result is True
@ -138,8 +143,9 @@ def test_are_all_predecessors_fulfilled(data):
def test_are_all_predecessors_fulfilled__wrong(data):
manager = RunnableVerticesManager.from_dict(data)
vertex_id = "D"
is_loop = False
result = manager.are_all_predecessors_fulfilled(vertex_id)
result = manager.are_all_predecessors_fulfilled(vertex_id, is_loop=is_loop)
assert result is False