You can run blocking, compute-intensive functions using run_in_executor:
def compute_intensive_function() -> int:
time.sleep(1)
return 42
async def f() -> int:
result = await asyncio.get_running_loop().run_in_executor(None, compute_intensive_function)
return result
The first argument is a concurrent.futures.Executor. When None is passed, the default executor is lazily instantiated, which by default is a concurrent.futures.ThreadPoolExecutor.
.
The documentation for ThreadPoolExecutor mentions that it will by default spawn
min(32, (os.process_cpu_count() or 1) + 4)
threads. Now here's the point where I'm going to be opinionated. I consider this too many threads for text editor plugins. For a server? Sure. Not for a text editor.
Because we already have a thread available to us for compute-intensive work, we should utilize that thread. This issue proposes we do that.
In my exploratory library I wrote such an executor here: https://github.com/sublimelsp/sublime_asyncio/blob/master/executor.py
It is hooked up to the loop here: https://github.com/sublimelsp/sublime_asyncio/blob/6a8eb2dbd36c72b34eb0078bc1b3cb96f1692acb/globalstate.py#L71
This will cause calls like this:
async def f() -> int:
result = await asyncio.get_running_loop().run_in_executor(None, compute_intensive_function)
return result
to use ST's async thread. Yes, you can still pass a custom executor that spawns too many threads for a text editor. Like bringing a leaf blower to move a single leaf. But that's every plugin author's deliberate choice then.
You can run blocking, compute-intensive functions using run_in_executor:
The first argument is a
concurrent.futures.Executor. WhenNoneis passed, the default executor is lazily instantiated, which by default is aconcurrent.futures.ThreadPoolExecutor..
The documentation for ThreadPoolExecutor mentions that it will by default spawn
threads. Now here's the point where I'm going to be opinionated. I consider this too many threads for text editor plugins. For a server? Sure. Not for a text editor.
Because we already have a thread available to us for compute-intensive work, we should utilize that thread. This issue proposes we do that.
In my exploratory library I wrote such an executor here: https://github.com/sublimelsp/sublime_asyncio/blob/master/executor.py
It is hooked up to the loop here: https://github.com/sublimelsp/sublime_asyncio/blob/6a8eb2dbd36c72b34eb0078bc1b3cb96f1692acb/globalstate.py#L71
This will cause calls like this:
to use ST's async thread. Yes, you can still pass a custom executor that spawns too many threads for a text editor. Like bringing a leaf blower to move a single leaf. But that's every plugin author's deliberate choice then.