Thomas Busath
10/16/2024, 2:47 PMto_async method of bentoml services.
I ran a couple load tests locally with the following code:
import bentoml
import time
import asyncio
import random
@bentoml.service(workers=4)
class LongRunningService:
@bentoml.api
async def long_running_task_async(self, n: int):
await asyncio.sleep(n)
return random.random()
@bentoml.api
def long_running_task(self, n: int):
time.sleep(n)
return random.random()
@bentoml.service(
workers=1
)
class svc:
long_running_service = bentoml.depends(LongRunningService)
@bentoml.api
async def predict(self, inputs: str) -> str:
# x = await self.long_running_service.to_async.long_running_task(n=3)
x = await self.long_running_service.long_running_task_async(n=3)
return f"{x}"
When I use the x = await self.long_running_service.long_running_task_async(n=3) function, all requests are returned within 3 seconds because long_running_task_async utilizes asyncio.sleep(n) which is non blocking. Conversely, when I use the x = await self.<http://long_running_service.to|long_running_service.to>_async.long_running_task(n=3) , requests begin stacking up in the internal queue and the response time gradually grows. Is this expected behavior? Based on the docs, I would've assumed that to_async would've turned the function into non-blocking code like the long_running_task_async() function .Jian Shen Yap
10/17/2024, 12:25 AMsvc in your case.
However in the LongRunningService , time.sleep is still a blocking code, so as requests stacks up, LongRunningService eventually gets blocked because within the service it is still a synchronous function.
CC : @Frost Ming for clarificationFrost Ming
10/17/2024, 12:45 AMtime.sleep() due to the default thread capacity=1Thomas Busath
10/17/2024, 2:59 PM