Skip to content

Commit 2879179

Browse files
test: enforce fail-fast acquire_sync behavior in async contexts
Agent-Logs-Url: https://github.com/MervinPraison/PraisonAI/sessions/c9e7c913-a80d-474a-bd5d-731c129ad614 Co-authored-by: MervinPraison <454862+MervinPraison@users.noreply.github.com>
1 parent ec2c519 commit 2879179

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

src/praisonai-agents/praisonaiagents/agent/concurrency.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,26 @@ def acquire_sync(self, agent_name: str) -> None:
8787
"""Synchronous acquire — for non-async code paths.
8888
8989
Prefer async acquire() when possible.
90+
If called while an event loop is already running in the current thread,
91+
this method raises RuntimeError to avoid deadlock.
9092
"""
9193
sem = self._get_semaphore(agent_name)
9294
if sem is None:
9395
return
9496
try:
9597
asyncio.get_running_loop()
96-
# Running loop in current thread: blocking here can deadlock.
97-
logger.warning(
98-
f"acquire_sync('{agent_name}') called with a running event loop; "
99-
"use async acquire() in async contexts."
100-
)
101-
return
10298
except RuntimeError:
10399
# No running loop — safe to create one
104100
loop = asyncio.new_event_loop()
105101
try:
106102
loop.run_until_complete(sem.acquire())
107103
finally:
108104
loop.close()
105+
else:
106+
raise RuntimeError(
107+
f"acquire_sync('{agent_name}') cannot be called with a running event loop; "
108+
"use async acquire() in async contexts."
109+
)
109110

110111
def release(self, agent_name: str) -> None:
111112
"""Release concurrency slot for agent. No-op if unlimited."""

src/praisonai-agents/tests/unit/agent/test_agent_concurrency.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,15 @@ def test_sync_acquire_release(self):
109109

110110
@pytest.mark.asyncio
111111
async def test_sync_acquire_running_loop_noop(self):
112-
"""Sync acquire in async context should not block event loop."""
112+
"""Sync acquire in async context should fail fast without changing state."""
113113
from praisonaiagents.agent.concurrency import ConcurrencyRegistry
114114
reg = ConcurrencyRegistry()
115115
reg.set_limit("loop_agent", 1)
116116
await reg.acquire("loop_agent")
117-
reg.acquire_sync("loop_agent")
117+
with pytest.raises(RuntimeError, match="running event loop"):
118+
reg.acquire_sync("loop_agent")
119+
with pytest.raises(asyncio.TimeoutError):
120+
await asyncio.wait_for(reg.acquire("loop_agent"), timeout=0.05)
121+
reg.release("loop_agent")
122+
await asyncio.wait_for(reg.acquire("loop_agent"), timeout=0.05)
118123
reg.release("loop_agent")

0 commit comments

Comments
 (0)