Will std.Io implement "Structured Concurrency"?

By “structured concurrency” I am talking about the ideas expressed in " Notes on structured concurrency, or: Go statement considered harmful" by Nathaniel J. Smith.

My understanding is “structured concurrency” has the following properties:

  1. Tasks may only be spawned by some sort of task group object
  2. Awaiting the task group is guaranteed to await (or cancel) all of the task groups child tasks.

which provides the following benefits:

  1. When a task concludes, one can know that there are no unfinished, dangling tasks spawned from that task.

This is kind of like giving an arena allocator to a function and being confident there are no leaks:

var arena = std.heap.ArenaAllocator.init(gpa);
defer arena.deinit() // look mom! no leaks!
do_complex_allocations(arena.allocator())

To what extent (or not) will std.Io implement “structured concurrency” and why?

2 Likes

there are groups, but it isnt required.

Yes, but cancellation is a separate operation.

Tasks are required to be awaited or cancelled, so yes.

std.Io doesn’t implement ‘structured concurrency’ but you can certainly mimic its style. I expect most use cases will.
std.Io is ‘structured concurrency’ assuming it is used soundly.

You can certainly implement, and i expect std will eventually, an ArenaIo that could enforce this, or clean up, both can be provided.

4 Likes

I might be mistaken, but I think Future’s contract is that you must call .await or .cancel, which I think actually gives you structured concurrency!

5 Likes

you are right, edited my original comment.

sorry for intervening.
event-driven-state-machines (if you implement them properly)
have “structured concurrency” just by theirs’ nature.

Actually I do not know what approach to achieve concurrency is “better”, coroutines or edsm… well, just a question - can a coroutine pass some arbitrary data to any coroutine at any moment?

I mean, for example, this:

int mep2_init_M1(struct edsm *src, struct edsm *me, void *dptr)
{
     struct upsdaq *ud = me->data;
     struct upsd_client *udc = &ud->udc;
     udc->conn_sm = src;  // store a pointer to connector machine
....

Here I used only the pointer to a machine which sent M1 message,
but that machine could also had been passed some additional data via dptr.

You can construct your program as a (sometimes very cool :slight_smile: ) team of edsms,
can you do that with coroutines?

1 Like