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

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(): a function returning the runtime's clock
  • tonio.sleep(delay): a coroutine you can yield on to sleep (delay is in seconds)
  • tonio.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).

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

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.0a2.tar.gz (33.9 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.0a2-cp314-cp314t-musllinux_1_1_x86_64.whl (556.1 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

tonio-0.1.0a2-cp314-cp314t-musllinux_1_1_armv7l.whl (619.1 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

tonio-0.1.0a2-cp314-cp314t-musllinux_1_1_aarch64.whl (512.5 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

tonio-0.1.0a2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (342.0 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

tonio-0.1.0a2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (349.3 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

tonio-0.1.0a2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (328.8 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

tonio-0.1.0a2-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl (372.5 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.12+ i686

tonio-0.1.0a2-cp314-cp314t-macosx_11_0_arm64.whl (296.1 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

tonio-0.1.0a2-cp314-cp314t-macosx_10_12_x86_64.whl (315.1 kB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: tonio-0.1.0a2.tar.gz
  • Upload date:
  • Size: 33.9 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.0a2.tar.gz
Algorithm Hash digest
SHA256 cf546579605a21e413a0c5ba3126f340ff47c60646187e63a3d891fde4bd6275
MD5 6efb758ed23933719d6a60451ee76a9f
BLAKE2b-256 ed85281f1ff63b415d0226a7b3a6db8b27ad97623fa926cac4ecb2bc04e7f305

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2.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.0a2-cp314-cp314t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6f0cf1691918b9b10122fed9e2f95fbfe5757e61f6334821336f45978f2fd968
MD5 3b80ca8c8586f62d4a6e09fe94b34840
BLAKE2b-256 60e4795fbb8a039688067b32766d841ba8fd282b496b33f8334b4375cf34f4f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 77a884cffd4beb4310389c08798b30edd7434c2f324676132d33652f32d5df54
MD5 d030d005d0e09824d05fe1dfa34a8a99
BLAKE2b-256 dae2b749daf2360851ec5b66050dd13deaa112d45b35b93b6efbd73913341b2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 28ee9b49e32f8be4f867e5f860f65f838081a7590f5feca635b91ca33a73b0a7
MD5 bdc6f9562d9632974007e8a38c626819
BLAKE2b-256 924ad5e75cb7511f55fdb693e853ae62967004b1efc0eef9f0153dbbf587fe9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c08fc172fe0f9f47b6ceffc8a0eef4a3c1934915b9adf67066ac189011d117ae
MD5 b3387e24ea577080727f668a3feaf9b0
BLAKE2b-256 107a59f2ffb71311af8ed1e2523a458dde000540a984243d93abbc93f8a1b274

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 84aca53923bd98e1cbe83b400ea301e616ed90f17632783a25666308376b11dc
MD5 c1dcbab54537edc481949ba546d670e5
BLAKE2b-256 e64774f1266cdf80aece41c491ca298c8c8e365cb5626875a05bd994324ac45f

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 eabd24119350515ee8e9a3eb270c0fef8ac0d1839e137fdfa1f7069ead46b91c
MD5 b012b24bcf19a408701746354db4a210
BLAKE2b-256 f6af898eae390cc8bab78de02a5cba03e63fda08a6823f1f2403436aa1defa29

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 5d4415f2806d0069b85e65d32e4d277010fe6b197a7f1b482e6ec7835de2d874
MD5 e55eae0596019cb0e54642cf6c54a57a
BLAKE2b-256 8162fe94764b90172505e70e04d0595339fffae246f9174f85241a18fd9b7219

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 607b9040af66addad2f891aef8dfb0deee61a540b79761f585f32e8d71b7d166
MD5 e436a76e6af4d637e151868ad62c1b38
BLAKE2b-256 c18208add506bc4e2fbfee27d477ad9be70c8913ea294d7b5b26279fbc8cb6a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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.0a2-cp314-cp314t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.1.0a2-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 482ff93db24d2a88f4c6a2e96613c8f6cf076c791d48ed2d630a495fe44d5081
MD5 a531e434000fe0639dce04ee23eb0080
BLAKE2b-256 966d321ba23cb56bd19eb95ab88ddbc0399564d2ab4b473b705babb4216d8b8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.1.0a2-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