Skuld.Effects.Cell (skuld_concurrency v0.47.0)

View Source

Single-writer, multi-reader mutable state for concurrent fibers.

Any fiber can read a Cell; the first fiber to write to a tag claims ownership. Only that fiber may write again — writes from other fibers error.

All operations require an explicit tag. There is no default tag.

Usage

comp do
  # Any fiber can read
  value <- Cell.get(:results)

  # First write claims ownership
  _ <- Cell.put(:results, data)

  # Re-writes by owner are fine
  _ <- Cell.put(:results, new_data)

  # Write from non-owner raises
end
|> Cell.with_handler()
|> FiberPool.with_handler()
|> Comp.run()

Summary

Functions

Watch a Cell tag, returning a Channel that will deliver the value.

Install the Cell handler for a computation.

Functions

state_key(tag)

watch(tag)

@spec watch(term()) :: Skuld.Comp.Types.computation()

Watch a Cell tag, returning a Channel that will deliver the value.

Returns a Channel.Handle for a capacity-1 channel:

  • If the Cell has already been written to, the channel contains the current value and is closed.
  • If the Cell has not been written to, the channel is empty. When Cell.put/2 writes to the tag, the value is delivered to all watcher channels and each channel is closed.

The returned channel never blocks the writer — capacity 1 with immediate close means Cell.put always succeeds without suspension.

Requires Channel.with_handler/1 to be installed.

Example

comp do
  watch_fiber <- FiberPool.fiber(comp do
    ch <- Cell.watch(:results)
    Channel.take(ch)
  end)

  writer <- FiberPool.fiber(comp do
    _ <- Cell.put(:results, [1, 2, 3])
    :ok
  end)

  result <- FiberPool.await!(watch_fiber)
  # result == {:ok, [1, 2, 3]}
end
|> Cell.with_handler()
|> Channel.with_handler()
|> FiberPool.with_handler()
|> Comp.run()

with_handler(computation)

Install the Cell handler for a computation.

Must be installed inside the FiberPool handler stack (after FiberPool.with_handler/1) so that FiberPool.current_fiber_id/1 can identify the writing fiber.