python-trio / trio-asyncio

a re-implementation of the asyncio mainloop on top of Trio
Other
187 stars 37 forks source link

`TrioExecutor` acquires the capacity limiter too many times. #116

Open 1ekf opened 1 year ago

1ekf commented 1 year ago

TrioExecutor shares the limiter with the underlying trio.to_thread.run_sync call, so more tokens are consumed than are intended.

Reproducible example:

import asyncio
import trio_asyncio

async def amain():
    loop = asyncio.get_event_loop()
    executor = trio_asyncio.TrioExecutor(max_workers=1)
    await loop.run_in_executor(executor, print, "hello")

trio_asyncio.run(trio_asyncio.aio_as_trio(amain))

This call will always block, as TrioExecutor acquires the only token available and the inner trio.to_thread.run_sync cannot acquire its own token.

1ekf commented 1 year ago

Since trio.to_thread.run_sync always acquires a token before spawning a thread, it seems sufficient to remove capacity limiter acquire/release in the TrioExecutor.submit implementation.