Sync vs Async Commands¶
If you're using third-party libraries that require
await, such as
Declare your command using
If your command contains blocking synchronous code (e.g., using the
requests library or
time.sleep), declare it using
Only Fast Code¶
For commands that don't need to wait for external responses or perform long computations, you can use both
async def and
If you just don't know, use normal
Mix of Blocking and Async¶
If your command contains both blocking code and
await-requiring asynchronous code, you'll need to use asyncer. There are two methods:
1. Recommended: Declare the command with
async def, use
await for asynchronous functions, and wrap blocking code in
import asyncer import requests @manager.new('hello') async def hello_command() -> Response: await some_library() # asynchronous function await asyncer.asyncify(requests.get)('https://stark.markparker.me/') # converted to asynchronous text = voice = 'Hello, world!' return Response(text=text, voice=voice)
2. Use a regular
def for the command, execute blocking functions as-is, and wrap asynchronous functions in
All commands in Stark are inherently asynchronous. If you declare a command as synchronous, Stark converts it to asynchronous using asyncer.asyncify.
By default, Stark concurrently manages two vital processes: speech transcription and response handling. It also has to execute commands, adding temporary processes that last as long as the command. All these processes share a single main thread. If one process blocks the thread for an extended period (e.g., with
time.sleep), it can halt the entire application. Stark includes the
BlockageDetector to monitor the main thread and alert you if it's blocked for longer than a specified duration (default is 1 second).
For commands that might cause blockages, declaring them using def is advised. Stark will then wrap these commands with asyncer.asyncify, spawning separate background threads for each process.
When using async def, care should be taken to prevent the main thread from being blocked. This can be achieved by avoiding long-blocking code and opting for asynchronous libraries like
aiohttp over synchronous ones such as
asyncer.asyncify can be used to wrap blocking sections of code.