File size: 918 Bytes
114194d
 
bd469c1
114194d
 
bd469c1
114194d
 
 
 
 
 
bd469c1
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from __future__ import annotations

import asyncio
import concurrent.futures
import os
from typing import Any, Callable

_MAX_WORKERS = min(32, (os.cpu_count() or 1) + 4)

thread_pool = concurrent.futures.ThreadPoolExecutor(
    max_workers=_MAX_WORKERS, thread_name_prefix="shared"
)


async def run_in_executor(fn: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
    """Run a blocking/cpu-bound callable on the shared thread pool.

    Centralises the repeated ``loop.run_in_executor(thread_pool, ...)`` pattern so
    async routes never block the event loop on sync I/O or CPU work. Uses the
    shared pool so a bounded number of threads is reused across the application.
    """
    if kwargs:
        return await asyncio.get_running_loop().run_in_executor(
            thread_pool, lambda: fn(*args, **kwargs)
        )
    return await asyncio.get_running_loop().run_in_executor(thread_pool, fn, *args)