This page shows practical ways to use rsloop.
All examples use normal Python asyncio patterns. The difference is that rsloop provides the event loop implementation.
This is the simplest starting point:
import rsloop
async def main() -> None:
print("hello from rsloop")
rsloop.run(main())Use this style when your program has one main async entry point.
This looks almost the same as standard asyncio:
import asyncio
import rsloop
async def worker(name: str) -> str:
await asyncio.sleep(0.1)
return f"{name} done"
async def main() -> None:
task1 = asyncio.create_task(worker("first"))
task2 = asyncio.create_task(worker("second"))
results = await asyncio.gather(task1, task2)
print(results)
rsloop.run(main())If your app already uses asyncio.create_task(...), await, and gather(...), moving to rsloop is usually straightforward.
Manual loop creation is useful when you want explicit setup and cleanup:
import asyncio
import rsloop
async def main() -> None:
print("running on", type(asyncio.get_running_loop()).__name__)
loop = rsloop.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(main())
finally:
asyncio.set_event_loop(None)
loop.close()Use this style if your program manages the loop lifecycle itself.
rsloop.Loop supports the familiar callback APIs:
import rsloop
loop = rsloop.new_event_loop()
def say(message: str) -> None:
print(message)
loop.stop()
loop.call_later(0.5, say, "timer fired")
loop.run_forever()
loop.close()This is useful when reading older asyncio code that still uses callbacks instead of only coroutines.
You can use socket helpers directly on the running loop:
import asyncio
import socket
import rsloop
async def main() -> None:
loop = asyncio.get_running_loop()
left, right = socket.socketpair()
left.setblocking(False)
right.setblocking(False)
try:
await loop.sock_sendall(left, b"ping")
data = await loop.sock_recv(right, 4)
print(data.decode())
finally:
left.close()
right.close()
rsloop.run(main())Use this style when you need lower-level control than streams provide.
rsloop supports the normal protocol and transport style:
import asyncio
import rsloop
class EchoProtocol(asyncio.Protocol):
def connection_made(self, transport: asyncio.BaseTransport) -> None:
self.transport = transport
def data_received(self, data: bytes) -> None:
self.transport.write(data.upper())
async def main() -> None:
loop = asyncio.get_running_loop()
server = await loop.create_server(EchoProtocol, "127.0.0.1", 9000)
try:
print("serving on 127.0.0.1:9000")
await asyncio.sleep(60)
finally:
server.close()
await server.wait_closed()
rsloop.run(main())This is a good fit when your project already uses asyncio.Protocol.
Because rsloop can patch stream helpers, high-level stream code can stay familiar:
import asyncio
import rsloop
async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
data = await reader.read(100)
writer.write(data.upper())
await writer.drain()
writer.close()
await writer.wait_closed()
async def main() -> None:
server = await asyncio.start_server(handle_client, "127.0.0.1", 9001)
try:
reader, writer = await asyncio.open_connection("127.0.0.1", 9001)
writer.write(b"hello")
await writer.drain()
print((await reader.read(100)).decode())
writer.close()
await writer.wait_closed()
finally:
server.close()
await server.wait_closed()
rsloop.run(main())This is often the easiest path for developers who already use high-level asyncio streams.
Not everything has to be async:
import asyncio
import rsloop
def blocking_sum() -> int:
return sum(range(100000))
async def main() -> None:
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(None, blocking_sum)
print(result)
rsloop.run(main())Use this when you must call blocking Python code without freezing the event loop.
rsloop also supports subprocess workflows:
import asyncio
import rsloop
import sys
async def main() -> None:
proc = await asyncio.create_subprocess_exec(
sys.executable,
"-c",
"print('hello from child')",
stdout=asyncio.subprocess.PIPE,
)
stdout, _ = await proc.communicate()
print(stdout.decode().strip())
rsloop.run(main())This is useful for scripts, tooling, and service code that needs to call external programs.
For fuller examples, read the repository files in examples/:
01_basics.py02_fd_and_sockets.py03_streams.py04_unix_and_accepted_socket.py05_pipes_signals_subprocesses.py