From 39f0005160208ffc5784d43c9182f156ca1fe5d6 Mon Sep 17 00:00:00 2001 From: David Clute Date: Mon, 1 Jun 2026 14:53:41 -0600 Subject: [PATCH] Fix #3374: Fully populate adversary and planner objects in scheduled operations --- app/service/app_svc.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/service/app_svc.py b/app/service/app_svc.py index 8afd2b82a..97c8f2031 100644 --- a/app/service/app_svc.py +++ b/app/service/app_svc.py @@ -104,15 +104,29 @@ async def run_scheduler(self): sop.id = str(uuid.uuid4()) sop.name += f" ({datetime.now(timezone.utc).replace(microsecond=0).isoformat()})" sop.set_start_details() + if sop.adversary: + full_adv = await self.get_service('data_svc').locate('adversaries', match=dict(adversary_id=sop.adversary.adversary_id)) + if full_adv: + sop.adversary = full_adv[0] + if sop.planner: + full_planner = await self.get_service('data_svc').locate('planners', match=dict(planner_id=sop.planner.planner_id)) + if full_planner: + sop.planner = full_planner[0] + if sop.source: + full_source = await self.get_service('data_svc').locate('sources', match=dict(id=sop.source.id)) + if full_source: + sop.source = full_source[0] await sop.update_operation_agents(self.get_services()) await self._services.get('data_svc').store(sop) - self.loop.create_task(sop.run(self.get_services())) + # Force the task onto the actively running asyncio loop instead of waiting for the next scheduler loop to run it + asyncio.get_running_loop().create_task(sop.run(self.get_services())) await asyncio.sleep(interval) async def resume_operations(self): await asyncio.sleep(10) for op in await self.get_service('data_svc').locate('operations', match=dict(finish=None)): - self.loop.create_task(op.run(self.get_services())) + # Force the task onto the actively running asyncio loop + asyncio.get_running_loop().create_task(op.run(self.get_services())) async def load_plugins(self, plugins): def trim(p):