(
agent_id: uuid.UUID,
paths: list[str],
*,
ttl_seconds: int = DEFAULT_LOCK_TTL_SECONDS,
)
| 55 | |
| 56 | @asynccontextmanager |
| 57 | async def workspace_locks( |
| 58 | agent_id: uuid.UUID, |
| 59 | paths: list[str], |
| 60 | *, |
| 61 | ttl_seconds: int = DEFAULT_LOCK_TTL_SECONDS, |
| 62 | ): |
| 63 | normalized = sorted({_normalize_workspace_path(path) or "." for path in paths if path is not None}) |
| 64 | owner_token = uuid.uuid4().hex |
| 65 | acquired: list[str] = [] |
| 66 | try: |
| 67 | for path in normalized: |
| 68 | ok = await acquire_workspace_lock( |
| 69 | agent_id, |
| 70 | path, |
| 71 | owner_token=owner_token, |
| 72 | ttl_seconds=ttl_seconds, |
| 73 | ) |
| 74 | if not ok: |
| 75 | raise RuntimeError(f"Workspace lock busy: {path}") |
| 76 | acquired.append(path) |
| 77 | yield |
| 78 | finally: |
| 79 | for path in reversed(acquired): |
| 80 | await release_workspace_lock(agent_id, path, owner_token=owner_token) |
no test coverage detected