Troupe:multi-role finite state machine

Multi-role finite state machine, used for multithreaded programs or distributed programs.

The behaviors of multiple characters are orchestrated into a state machine. Imagine a theater with many characters performing a play. The behaviors of all characters are arranged as a whole in the script. When a certain message is sent, everyone will complete their performance according to the script.

Some similar libraries:

  1. Home - Choral Language Website
  2. GitHub - gshen42/HasChor: Functional choreographic programming in Haskell

This project was initially called “polysession,” and I only intended it for developing multi-role communication protocols.

However, I later discovered its uses extend far beyond communication protocols. For example, you can use it to create game scripts and write multi-threaded programs.

When there is only one participating role, troupe is equivalent to polystate. Or, you can consider polystate as a special case of troupe.

2 Likes

The troupe allows you to construct the overall control flow of your program through declarative composition and generates the overall control flow diagram through the compiler.

For example, the above definition will generate the following control chart:

The effect during runtime:
GIF 2025-11-16 09-27-54

5 Likes

I don’t understand it at all, but from your descriptions it seems like something sublime

The stacked coroutines have been merged into master.

A troupe is a framework describing multi-role communication. Using evented, we’ll use one million pairs of pingpong protocols, representing two million fibers.

Each pair of fibers in the pingpong protocol will send messages to each other 30 times.

zig build pingpong --release=fast

It took about 10 seconds to complete on my PC.

ps: I set the value of A here to 1 * 1024.

It doesn’t have networking yet, but for anything needing concurrency for local IO, it seems to be there and working reasonably okay.

Unless you’re debugging IoUring.zig itself, I’d recommend adding the following to your root module as it currently has some quite verbose debug logging.

const std_options: std.Options = .{
    .log_scope_levels = &.{ .{ .scope = .@"io-uring", .level = .info } },
};

Not the author of it, just someone who has been following development closely and been toying around with it since the PR was made a little while ago.

1 Like