Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 5 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
</div>
<br>

[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE.md) [![Build](https://github.com/UIBK-DPS-DC/Cirrina/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/UIBK-DPS-DC/Cirrina/actions/workflows/build.yml?event=push) [![Docker Image Version (tag)](https://img.shields.io/docker/v/collaborativestatemachines/cirrina/unstable?color=red)](https://hub.docker.com/repository/docker/collaborativestatemachines/cirrina/tags/unstable/) [![Docker Image Version (tag)](https://img.shields.io/docker/v/collaborativestatemachines/cirrina/stable?color=blue)](https://hub.docker.com/repository/docker/collaborativestatemachines/cirrina/tags/stable/)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE.md)
[![Build](https://github.com/UIBK-DPS-DC/Cirrina/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/UIBK-DPS-DC/Cirrina/actions/workflows/build.yml?event=push)
[![Docker Image Version (tag)](https://img.shields.io/docker/v/collaborativestatemachines/cirrina/stable?color=blue)](https://hub.docker.com/layers/collaborativestatemachines/cirrina/stable/)
[![Docker Image Version (tag)](https://img.shields.io/docker/v/collaborativestatemachines/cirrina/unstable?color=red)](https://hub.docker.com/layers/collaborativestatemachines/cirrina/unstable)

Cirrina, a distributed Collaborative State Machines (CSM) runtime for the Cloud-Edge-IoT continuum.
Collaborative State Machines is a state machine-based programming model for the Cloud-Edge-IoT
Collaborative State Machines is a state-machine-based programming model for the Cloud-Edge-IoT
continuum. For more information, please visit
the [Project Website](https://collaborativestatemachines.github.io/).

Expand All @@ -17,19 +20,3 @@ the [Distributed and Parallel Systems Group of the
University Innsbruck](https://dps.uibk.ac.at/).

For contributions, please see the [Contribution Guidelines](CONTRIBUTING.md).

To deploy Cirrina using Kubernetes, see the [Helm Chart](charts/cirrina).

## Citing

```
@misc{etheredge2025collaborativestatemachinesbetter,
title={Collaborative State Machines: A Better Programming Model for the Cloud-Edge-IoT Continuum},
author={Marlon Etheredge and Thomas Fahringer and Felix Erlacher and Elias Kohler and Stefan Pedratscher and Juan Aznar-Poveda and Nishant Saurabh and Adrien Lebre},
year={2025},
eprint={2507.21685},
archivePrefix={arXiv},
primaryClass={cs.DC},
url={https://arxiv.org/abs/2507.21685},
}
```
15 changes: 15 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Cirrina Examples

This directory contains a collection of examples.

To run an example on multiple isolated resources, we recommend
using [Vagrant](https://developer.hashicorp.com/vagrant).

To execute the [helloWorld](tutorial/helloWorld.pkl) example, run:

```
./cirrina \
RUN=one,two \
MAIN_URI=file:///examples/tutorial/helloWorld.pkl \
ETCD_CONTEXT_URL=http://localhost:2379
```
116 changes: 116 additions & 0 deletions examples/concurrency/big.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
amends
"https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl"

local n = 12

collaborativeStateMachine {
stateMachines {
["big"] {
transient { ["count"] = "0" }
states {
["register"] = new Initial {
entry { new Emit { event { topic = "register" }; target = "'sink'" } }
on {
["initial"] = new Transition {
to = "run"
}
}
}
["run"] = new State {
entry {
new Eval { expression = "++count" }
new Ctr { counter = "big.pings" }
new Emit {
event {
topic = "ping"
data { ["sender"] = "id" }
}
target = "std:takeRandom(peers).toString()"
}
}
on {
["ping"] {
yields {
new Emit {
event {
topic = "pong"
data { ["sender"] = "id" }
}
target = "$sender.toString()"
}
}
}
["pong"] {
yields {
new Match {
cases {
new Case {
of = "count % 1000 == 0"
yields {
new Emit { event { topic = "report" } }
}
}
}
}
new Eval { expression = "++count" }
new Ctr { counter = "big.pings" }
new Emit {
event {
topic = "ping"
data { ["sender"] = "id" }
}
target = "std:takeRandom(peers).toString()"
}
}
}
}
}
}
}
["sink"] = new StateMachine {
transient {
["total"] = "0"
["registered"] = "0"
}
states {
["wait"] = new Initial {
on {
["register"] = new Transition {
yields {
new Eval { expression = "++registered" }
new Match {
cases {
new Case {
of = "registered == 12"
yields {
new Emit { event { topic = "initial" } }
}
}
}
}
}
}
["report"] {
yields {
new Eval { expression = "total += 1000" }
new Ctr { counter = "sink.total"; by = 1000 }
}
}
}
}
}
}
}
}
instances {
["sink"] { stateMachineName = "sink" }
for (i in IntSeq(0, n - 1)) {
["\(i)"] {
stateMachineName = "big"
data {
["id"] = "\(i)"
["peers"] = "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - [\(i)]"
}
}
}
}
100 changes: 100 additions & 0 deletions examples/concurrency/chameneos.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
amends "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl"

local n = 12

collaborativeStateMachine {
stateMachines {
["chameneos"] {
transient {
["color"] = "std:takeRandom([1,2,3,...])"
}
states {
["request"] = new Initial {
entry {
new Emit {
event {
topic = "requesting"
data { ["id"] = "id"; ["color"] = "color" }
}
target = "'mall'"
}
}
on {
["matchMade"] = new Transition {
to = "request"
yields {
new Eval { expression = "color = (function (x,y) { if (x == y) {x} else {x ^ y} })(color, $color)" }
new Emit {
event {
topic = "change"
data { ["color"] = "color" }
}
target = "$partner.toString()"
}
}
}
["change"] = new Transition {
to = "request"
yields {
new Eval { expression = "color = $color" }
}
}
}
}
}
}
["mall"] {
transient {
["waiting"] = "[...]"
["count"] = "0"
}
states {
["wait"] = new Initial {
on {
["requesting"] = new Transition {
yields {
new Match {
cases {
new Case {
of = "waiting.isEmpty()"
yields { new Eval { expression = "waiting += [$id]" } }
}
new Case {
of = "!waiting.isEmpty()"
yields {
new Eval { expression = "++count" }
new Ctr { counter = "mall.meetings" }
new Emit {
event {
topic = "matchMade"
data {
["partner"] = "$id"
["color"] = "$color"
}
}
target = "waiting.get(0).toString()"
}
new Eval { expression = "waiting -= [waiting.get(0)]" }
}
}
}

}
}
}
}
}
}
}
}
}

instances {
["mall"] { stateMachineName = "mall" }
for (i in IntSeq(0, n - 1)) {
["\(i)"] {
stateMachineName = "chameneos"
data { ["id"] = "\(i)" }
}
}
}
67 changes: 67 additions & 0 deletions examples/concurrency/cigaretteSmokers.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
amends
"https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl"

local n = 3

collaborativeStateMachine {
stateMachines {
["arbiter"] {
transient {
["ingredients"] = "[0, 1, 2, ...]"
["count"] = "0"
}
states {
["run"] = new Initial {
entry {
new Eval { expression = "++count" }
new Ctr { counter = "arbiter.rounds" }
new Emit {
event {
topic = "provided"
data { ["ingredients"] = "ingredients - [std:takeRandom(ingredients)]" }
}
}
}
on {
["finish"] = new Transition { to = "run" }
}
}
}
}
["smoker"] {
states {
["wait"] = new Initial {
on {
["provided"] = new Transition {
to = "smoking"
provided = "!($ingredients.contains(id))"
}
}
}
["smoking"] = new State {
after {
["wait"] = new Timeout {
delay = "std:randomAround(10,2)"
triggers = new Emit { event = new Internal { topic = "continue" } }
}
}
on {
["continue"] = new Transition {
to = "wait"
yields { new Emit { event { topic = "finish" }; target = "'arbiter'" } }
}
}
}
}
}
}
}
instances {
["arbiter"] { stateMachineName = "arbiter" }
for (i in IntSeq(0, n - 1)) {
["\(i)"] {
stateMachineName = "smoker"
data { ["id"] = "\(i)" }
}
}
}
50 changes: 50 additions & 0 deletions examples/concurrency/count.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
amends
"https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl"

collaborativeStateMachine {
stateMachines {
["producer"] {
states {
["init"] = new Initial {
entry {
new Emit { event = new Internal { topic = "send" } }
}
on { ["send"] = new Transition { to = "send" } }
}
["send"] = new State {
after {
["send"] = new Timeout {
delay = "std:randomAround(10,2)"
triggers = new Emit { event = new Internal { topic = "send" } }
}
}
on {
["send"] = new Transition {
to = "init"
yields { new Emit { event { topic = "increment" } } }
}
}
}
}
}
["counter"] {
transient { ["count"] = "0" }
states {
["count"] = new Initial {
on {
["increment"] = new Transition {
yields {
new Eval { expression = "++count" }
new Ctr { counter = "counter.count" }
}
}
}
}
}
}
}
}
instances {
["counter"] { stateMachineName = "counter" }
["producer"] { stateMachineName = "producer" }
}
Loading
Loading