Skip to content

Commit

Permalink
Also record the overheads when running multiple stages concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
albireox committed Dec 6, 2023
1 parent 14ff740 commit 32737a3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
17 changes: 15 additions & 2 deletions src/hal/macros/macro.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,20 @@ async def _do_run(self):
current_task: asyncio.Future | None = None

for istage, stage in enumerate(self.stages):
coros = self._get_coros(stage)
print(coros)
wrapped_coros = [
asyncio.create_task(record_overhead(self)(coro))
for coro in self._get_coros(stage)
asyncio.create_task(record_overhead(self)(coro)) for coro in coros
]

# If we are running multiple stages concurrently, we also record the
# overhead of the entire set.
overhead_helper: OverheadHelper | None = None
if len(wrapped_coros) > 1:
costage_name = ":".join([coro.__name__ for coro in coros])
overhead_helper = OverheadHelper(self, costage_name)
await overhead_helper.start()

current_task = asyncio.gather(*wrapped_coros)

self.set_stage_status(stage, StageStatus.ACTIVE)
Expand Down Expand Up @@ -475,6 +484,10 @@ async def _do_run(self):
await self.fail_macro(err, stage=stage)
return

finally:
if overhead_helper is not None:
await overhead_helper.stop()

def get_active_stages(self):
"""Returns a list of running stages."""

Expand Down
21 changes: 18 additions & 3 deletions tests/macros/test_goto_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@

from __future__ import annotations

import asyncio

import pytest
from pytest_mock import MockerFixture

from hal.exceptions import MacroError


pytestmark = [pytest.mark.asyncio]
Expand All @@ -29,6 +34,7 @@ async def goto_field_macro(actor, command, mocker):
None,
None,
None,
False,
]

actor.models["tcc"]["axePos"].value = [100, 60, 0]
Expand All @@ -42,12 +48,21 @@ async def goto_field_macro(actor, command, mocker):
yield macro


async def test_goto_field_fails_tcc(goto_field_macro):
async def test_goto_field_fails_tcc(goto_field_macro, mocker: MockerFixture):
mocker.patch.object(goto_field_macro, "_all_lamps_off", return_value=True)

# This causes the slew stage to fail immediately since the first thing it does
# is sleep for a bit.
mocker.patch.object(asyncio, "sleep", side_effect=MacroError)
await goto_field_macro.run()

command = goto_field_macro.command

# Macros don't finish commands.
assert not goto_field_macro.command.status.is_done
assert not command.status.is_done
assert not goto_field_macro.running

reply_codes = [reply.flag for reply in goto_field_macro.command.actor.mock_replies]
reply_codes = [reply.flag for reply in command.actor.mock_replies]
assert "e" in reply_codes

assert command.replies[-1].message["stage_duration"][1] == "slew:reconfigure"

0 comments on commit 32737a3

Please sign in to comment.