feat(mma): Implement TrackDAG for dependency resolution and cycle detection
This commit is contained in:
52
dag_engine.py
Normal file
52
dag_engine.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from typing import List
|
||||
from models import Ticket
|
||||
|
||||
class TrackDAG:
|
||||
def __init__(self, tickets: List[Ticket]):
|
||||
self.tickets = tickets
|
||||
self.ticket_map = {t.id: t for t in tickets}
|
||||
|
||||
def get_ready_tasks(self) -> List[Ticket]:
|
||||
"""Returns tickets that are 'todo' and whose dependencies are all 'completed'."""
|
||||
ready = []
|
||||
for ticket in self.tickets:
|
||||
if ticket.status == 'todo':
|
||||
# Check if all dependencies exist and are completed
|
||||
all_done = True
|
||||
for dep_id in ticket.depends_on:
|
||||
dep = self.ticket_map.get(dep_id)
|
||||
if not dep or dep.status != 'completed':
|
||||
all_done = False
|
||||
break
|
||||
if all_done:
|
||||
ready.append(ticket)
|
||||
return ready
|
||||
|
||||
def has_cycle(self) -> bool:
|
||||
"""Returns True if there's a dependency cycle."""
|
||||
visited = set()
|
||||
rec_stack = set()
|
||||
|
||||
def is_cyclic(ticket_id):
|
||||
if ticket_id in rec_stack:
|
||||
return True
|
||||
if ticket_id in visited:
|
||||
return False
|
||||
|
||||
visited.add(ticket_id)
|
||||
rec_stack.add(ticket_id)
|
||||
|
||||
ticket = self.ticket_map.get(ticket_id)
|
||||
if ticket:
|
||||
for neighbor in ticket.depends_on:
|
||||
if is_cyclic(neighbor):
|
||||
return True
|
||||
|
||||
rec_stack.remove(ticket_id)
|
||||
return False
|
||||
|
||||
for ticket in self.tickets:
|
||||
if ticket.id not in visited:
|
||||
if is_cyclic(ticket.id):
|
||||
return True
|
||||
return False
|
||||
Reference in New Issue
Block a user