Source code for simstack.core.services.resource_branch_monitor_service

import asyncio
import logging

from simstack.core.context import context
from simstack.models.parameters import Resource
from simstack.models.runner_model import RunnerEventEnum
from simstack.models.resource_definition import ResourceDefinition
from simstack.core.services.base_service import RestartService

logger = logging.getLogger("NodeRunner")

[docs] class ResourceBranchMonitorService(RestartService): """ Monitors the ResourceDefinition for the current resource. If the git_branch field changes, it stashes, switches branch, syncs, and restarts. """ def __init__(self, resource: Resource, interval: int): super().__init__("ResourceBranchMonitor", resource, interval) self._project_dir = context.config.project_root.resolve(strict=True) async def _run_command(self, cmd: list) -> str: process = await asyncio.create_subprocess_exec( *cmd, cwd=str(self._project_dir), stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, stderr = await process.communicate() if process.returncode != 0: logger.error(f"Command {' '.join(cmd)} failed: {stderr.decode()}") return "" return stdout.decode().strip() async def _get_current_branch(self) -> str: return await self._run_command(["git", "rev-parse", "--abbrev-ref", "HEAD"])
[docs] async def execute(self): resource_def = await context.db.find_one( ResourceDefinition, ResourceDefinition.resource_str == str(self._resource) ) if not resource_def: return target_branch = resource_def.git_branch current_branch = await self._get_current_branch() if target_branch and current_branch and target_branch != current_branch: logger.info(f"Branch change detected: {current_branch} -> {target_branch}. Updating...") # 1. Stash existing changes await self._run_command(["git", "stash"]) # 2. Checkout new branch checkout_res = await self._run_command(["git", "checkout", target_branch]) if not checkout_res: logger.error(f"Failed to checkout branch {target_branch}") return # 3. UV Sync logger.info("Running uv sync --locked...") await self._run_command(["uv", "sync", "--locked"]) # 4. Trigger Restart await self.write_resource_event( RunnerEventEnum.SHUTDOWN, message=f"Branch switched to {target_branch}" ) await self.trigger_restart()