Skip to main content

Context-aware Flipper

The previous Flipper example stores all values in logic state — a central location that requires sequential access.

Flipper logic state

With a million users flipping values, each must wait for the previous one to finish.

Actor State: Parallel Execution​

MOI solves this by moving data from logic state to actor context. Each actor (user or logic) stores their own value, enabling parallel execution.

Flipper values on actor states

A million actors can flip their values simultaneously.

tip

Read more about state in Logic and Actor State.

Modified Code​

Create context_flipper.coco:

context_flipper.coco
coco ContextFlipper

state actor:
value Bool

endpoint dynamic Flip():
mutate value <- ContextFlipper.Sender.value:
value = !value

endpoint static Mode() -> (value Bool):
observe value <- ContextFlipper.Sender.value

endpoint dynamic Set(value Bool):
mutate value -> ContextFlipper.Sender.value

Key differences:

  • state actor instead of state logic
  • No initialization endpoint: an actor that has never written value reads it as false, the zero value of Bool
  • Access via Sender instead of Logic

Test the Code​

coco compile
coco lab init

Flip and Test​

Actor state needs no setup step. The sender's value starts as false and changes on the first Flip:

# Never written, so the logic reads the zero value
invoke ContextFlipper.Mode()
# → value:false

invoke ContextFlipper.Flip()
observe ContextFlipper.Sender.value
# → true
note

The observe command reads the stored slot directly, so for a value that has never been written it reports error: value not found. Endpoints never see that error. Inside the logic, an unwritten field reads as its zero value.

Multiple Ways to Observe​

All these return the same value:

observe ContextFlipper.Sender.value
observe ContextFlipper.default_user.value
observe ContextFlipper.<identifier>.value

Test with Another User​

register Robert
set default.sender Robert

# Each actor has their own value. Robert's has never been written
invoke ContextFlipper.Mode() # → value:false
observe ContextFlipper.default_user.value # → true (unchanged)

# Flip Robert's value twice
invoke ContextFlipper.Flip()
observe ContextFlipper.Robert.value # → true
invoke ContextFlipper.Flip()
observe ContextFlipper.Robert.value # → false
observe ContextFlipper.default_user.value # → still true

Actor context is the foundation of parallel execution in MOI.