Skip to main content

A multi-threaded async runtime

Project description

TonIO

TonIO is a multi-threaded async runtime for free-threaded Python, built in Rust on top of the mio crate, and inspired by tinyio and trio.

Warning: TonIO is currently a work in progress and very pre-alpha state. The APIs are subtle to breaking changes.

Note: TonIO is available on free-threaded Python and on Unix systems only.

In a nutshell

import tonio

def wait_and_add(x: int) -> int:
    yield tonio.sleep(1)
    return x + 1

def foo():
    four, five = yield tonio.spawn(wait_and_add(3), wait_and_add(4))
    return four, five

out = tonio.run(foo())
assert out == (4, 5)

Usage

Entrypoint

Every TonIO program consist of an entrypoint, which should be passed to the run method:

import tonio

def main():
    yield
    print("Hello world")

tonio.run(main())

TonIO also provides a main decorator, thus we can rewrite the previous example as:

import tonio

@tonio.main
def main():
    yield
    print("Hello world")

main()

Runtime options

Both run and main accept options, specifically:

option name description default
threads Number of runtime threads # of CPU cores
threads_blocking Maximum number of blocking threads 128
threads_blocking_timeout Idle timeout for blocking threads (in seconds) 30
context enable contextvars usage in coroutines False

Events

The core object in TonIO is Event. It's basically a wrapper around an atomic boolean flag, initialised with False. Event provides the following methods:

  • is_set(): return the value of the flag
  • set(): set the flag to True
  • clear(): set the flag to False
  • wait(timeout=None): returns a coroutine you can yield on that unblocks when the flag is set to True or the timeout expires. Timeout is seconds.
  • __call__(timeout=None): same of wait, but returns a coroutine you can await on.
import tonio

@tonio.main
def main():
    event = tonio.Event()

    def setter():
        yield tonio.sleep(1)
        event.set()

    tonio.spawn(setter())
    yield event.wait()

Spawning tasks

TonIO provides the spawn method to schedule new coroutines onto the runtime:

import tonio

def doubv(v):
    yield
    return v * 2

@tonio.main
def main():
    parallel = tonio.spawn(doubv(2), doubv(3))
    v3 = yield doubv(4)
    v1, v2 = yield parallel
    print([v1, v2, v3])

Coroutines passed to spawn get schedule onto the runtime immediately. Using yield on the return value of spawn just waits for the coroutines to complete and retreive the results.

Blocking tasks

TonIO provides the spawn_blocking method to schedule blocking operations onto the runtime:

import tonio

def read_file(path):
    with open(file, "r") as f:
        return f.read()

@tonio.main
def main():
    file_data = yield tonio.spawn_blocking(read_file, "sometext.txt")

Time-related functions

  • tonio.time.time(): a function returning the runtime's clock
  • tonio.time.sleep(delay): a coroutine you can yield on to sleep (delay is in seconds)
  • tonio.time.timeout(coro, timeout): a coroutine you can yield on returning a tuple (output, success). If the coroutine succeeds in the given time then the pair (output, True) is returned. Otherwise this will return (None, False).

Note: time.sleep is also exported to the main tonio module.

Synchronization primitives

Synchronization primitives are exposed in the tonio.sync module.

Lock

Implements a classic mutex, or a non-reentrant, single-owner lock for coroutines:

import tonio
import tonio.sync

@tonio.main
def main():
    # counter can't go above 1
    counter = 0

    def _count(lock):
        nonlocal counter
        with (yield lock()):
            counter += 1
            yield
            counter -= 1
    
    lock = tonio.sync.Lock()
    yield tonio.spawn(*[_count(lock) for _ in range(10)])

Semaphore

A semaphore for coroutines:

import tonio
import tonio.sync

@tonio.main
def main():
    # counter can't go above 2
    counter = 0

    def _count(lock):
        nonlocal counter
        with (yield lock()):
            counter += 1
            yield
            counter -= 1
    
    lock = tonio.sync.Semaphore(2)
    yield tonio.spawn(*[_count(lock) for _ in range(10)])

Barrier

A barrier for coroutines:

import tonio
import tonio.sync

@tonio.main
def main():
    barrier = tonio.sync.Barrier(3)
    count = 0

    def _start_at_3():
        nonlocal count
        count += 1
        i = yield barrier.wait()
        assert count == 3
        return i

    yield tonio.spawn(*[_start_at_3() for _ in range(3)])

Channels

Multi-producer multi-consumer channels for inter-coroutine communication.
The tonio.sync.channel module provides both a channel and unbounded constructors:

import tonio
import tonio.sync
import tonio.sync.channel as channel

def producer(sender, barrier, offset):
    for i in range(20):
        message = offset + 1
        yield sender.send(message)
    yield barrier.wait()

def consumer(receiver):
    while True:
        try:
            message = yield receiver.receive()
            print(message)
        except Exception:
            break

@tonio.main
def main():
    def close(sender, barrier):
        yield barrier.wait()
        sender.close()

    sender, receiver = channel.channel(2)
    barrier = tonio.sync.Barrier(3)
    yield tonio.spawn(*[
        producer(sender, barrier, 100),
        producer(sender, barrier, 200),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        close(sender, barrier),
    ])

Network module

Network primitives are exposed under the tonio.net module.

Low-level sockets

The tonio.net.socket module provides TonIO's basic low-level networking API.
Generally, the API exposed by this module mirrors the standard library socket module.

TonIO socket objects are overall very similar to the standard library socket objects, with the main difference being that blocking methods become coroutines.

import tonio
from toio.net import socket

def server():
    sock = socket.socket()
    with sock:
        yield sock.bind(('127.0.0.1', 8000))
        sock.listen()

        while True:
            client, _ = yield sock.accept()
            tonio.spawn(server_handle(client))

def server_handle(connection):
    with connection:
        # receive some data
        data = yield connection.recv(4096)

def client():
    sock = socket.socket()
    with sock:
        yield sock.connect(('127.0.0.1', 8000))
        yield sock.send("message")

Using async/await notation

All TonIO primitives ships with an async/await syntax compatible variant under the tonio.colored module.

Warning: despite the fact TonIO supports async and await notations, it's not compatible with any asyncio object like futures and tasks.

import tonio.colored as tonio

@tonio.main
async def main():
    event = tonio.Event()

    async def setter():
        await tonio.sleep(1)
        event.set()

    tonio.spawn(setter())
    await event()

The only major syntax difference between the yield and async/await notation is around with blocks:

from tonio.sync import Lock

lock = Lock()

def yield_lock():
    with (yield lock()):
        # do something

async def async_lock():
    async with lock:
        # do something

Also, the colored module provides the additional yield_now awaitable function, a quick way to define a suspension point:

import tonio.colored as tonio

@tonio.main
async def main():
    await tonio.yield_now()
    print("hello world")

License

TonIO is released under the BSD License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tonio-0.1.0a3.tar.gz (34.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_x86_64.whl (561.9 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_armv7l.whl (624.3 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_aarch64.whl (517.1 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (348.1 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (352.6 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (333.6 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

tonio-0.1.0a3-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl (376.8 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.12+ i686

tonio-0.1.0a3-cp314-cp314t-macosx_11_0_arm64.whl (300.0 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

tonio-0.1.0a3-cp314-cp314t-macosx_10_12_x86_64.whl (321.0 kB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

File details

Details for the file tonio-0.1.0a3.tar.gz.

File metadata

  • Download URL: tonio-0.1.0a3.tar.gz
  • Upload date:
  • Size: 34.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tonio-0.1.0a3.tar.gz
Algorithm Hash digest
SHA256 ec292467578803bc1e5af2a539e43c0619e1c9b8c79a5cef337bb8bab2b64d38
MD5 7c7b6b6406aa806918f69aa874972a64
BLAKE2b-256 d6e1209276eefd69f9411738eb5d1addfe273934ebb57fa24d027c72c434266f

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3.tar.gz:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 e4b86ef7c8691c8a1de4e6f90a92403b53c5448218491c6912d096640ce8fc0f
MD5 62a048896e51ac9becaea5fc71337310
BLAKE2b-256 7fcbca9da39291f4147485b5e360ac839beeb9f8ac38d03b2aff728ae33c08f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 d228c1dbfe7bdeb7976437b2df5fe6290b922b15fe5e829d3fccc10d5df5dd59
MD5 6c4ab5ad787a493ee4424a62734b7c40
BLAKE2b-256 748c261076b0f286c7bef73981565e417a61d4e9056b326cb2bff70e9e83482c

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_armv7l.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 699c50b0f96cc9bfdbf86a6541d764d671dacd57612434138de10a11ca9e0beb
MD5 f2feac298111e3d2fe89eaa641521cc7
BLAKE2b-256 63a14cac32ec612aacab166150c109c79a0b8d68257253b595dad913c38f110a

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-musllinux_1_1_aarch64.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1d2c3f226e40321ee4585aea126f949011e24b73c88fa768947c97c286389d10
MD5 a5c96303c39cd4225c098725eefa3b8b
BLAKE2b-256 346214a04f965d1998980f899f9829dc3dd055fef92dc3fcdb92e4cb75b431cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 edec3b8d77a8823d084684426dcccd3050e8d492b67b84b66a7d96d89bd3a499
MD5 2b315b446ff525a1514912c7e286880a
BLAKE2b-256 11d182e1b18ba0f02b689dc5e3badc6ef049681a4a43f2d537218a13dfef11fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 71d8272c30ee0213ee09e1ee7fb97ef4b63f58550dd755f9b31531b9393cef61
MD5 2e7099e2cb46f488f102eb58dfd0454b
BLAKE2b-256 fb14303fbdcf473ccfb03f9a8771c4b01b631169695e27c46619224aad142965

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 473038d2710a0598b4346c2d191ee4f7194c07687a6ddacf9afc49c7c8df0463
MD5 b9128fc8803036ee5cd01040135af9a9
BLAKE2b-256 5468dbd1979cd1f7def5b23c9cccb612b493a9f159e674e1ff8700eed0a29be5

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dae910dabc2c1659e7957e12c6ab6749d2e2be161a7c39d438fbd5a50580d06c
MD5 af753ec1def3334088721b2d24227884
BLAKE2b-256 02822a6b5742089829d0aeb3b1aa278e7825615e3eb0a9c13c5a2febc21ab95b

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-macosx_11_0_arm64.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonio-0.1.0a3-cp314-cp314t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a3-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 65fd87bcd55f805a22717dd0c47706c1a7a65aa864d116a11858345dc2030441
MD5 757eedae9e604d679ac9c789e89d6a6c
BLAKE2b-256 5f25449a345d616bba257d27a25e01face8251f85ca158967ca2c4af2c274606

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a3-cp314-cp314t-macosx_10_12_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page