lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On 12 Oct 2022, at 15:26, John Belmonte <> wrote:

On Wed, Oct 12, 2022 at 6:11 PM Thijs Schreijer <> wrote:
For example; if you run this on top of Copas, and a Trio task would call a Copas socket function (read/write/connect) it would do a Copas yield to the Trio scheduler (meaning it would pass the Copas socket and request (read/write) to Trio, which would not be expecting those.

For structured concurrency to work, it needs to be honored all the way down the stack.  And for the full API, it's not only about keeping child coroutines in the scope of the parent, but also about having a consistent and flexible cancellation scheme.  But everything in the program performing blocking I/O needs to cooperate.

That’s obvious

The Python ecosystem faces this problem too.  Python has async/await syntax, but, like Lua, it's very flexible about plugging in your own scheduler and ways to deal with parallel tasks (async/await says nothing about how to spawn a task).  So there is standard asyncio (which isn't that great, and predates async/await and learnings from trio), twisted, curio, trio, ... each having incompatible event loops, and using a different yield protocol.

"Sans I/O" libraries have emerged as a solution.  Such a library provides a synchronous (and hopefully, high quality) API, suitable for integration with any event loop (or none at all), effectively separating concerns between protocol logic and I/O.

This is libraries consuming the scheduler and IO functionalities

> h11 contains no IO code whatsoever. This means you can hook h11 up to your favorite network API, and that could be anything you want: synchronous, threaded, asynchronous, [...] Compare this to the current state of the art, where every time a new network API comes along then someone gets to start over reimplementing the entire HTTP protocol from scratch.

My question was whether trio could be written in such a way that is independent of the scheduler used.

The example you give; h11, of a sans-io library implements an api of “read-some-bytes” and “write-me-some-bytes” and then promises to do all thing HTTP on top of that.So it needs an api on top of the scheduler.

So if I have a scheduler that doesn’t keep track of parent-child hierarchy, but just implements “run-me-a-task” and “cancel-me-a-task”. Could trio be written in such a way that it implements structured concurrency on top of those “primitives”. Because why would trio have to reimplement all basic IO logic again?

So instead of “trio-being-scheduler -> api -> h11-library”

Using “primitive-scheduler -> api -> trio -> api ->h11-library"