smut
Dirty, dirty: Shared MUTable state.
Currently this package only supports the erlang target, but it’ll support
javascript eventually.
Obviously, this isn’t really shared, mutable state in the way that can
cause undefined behavior. On the erlang target, state is stored in an
ETS table. Reads consult the table directly, but writes are governed by
an Actor to ensure that updates are “atomic”. (That is, that no other
threads/tasks/processes can interfere with the value during or interrupt
the read-change-write compound operation involved in an update.)
The javascript target will behave similarly once it’s supported.
This package is not in any way for the kinds of optimizations that can be perpetrated by using mutable state; if you’re here for that, you’re using the entirely wrong language. This package is for ergonomy in dealing with things like rate limiters in web servers, where multiple threads of execution all need to be counting requests together.
smut is still under heavy development. Obviously.
Example
import gleam/erlang/process
import smut
pub fn main() {
let global_smut_table = smut.init()
let assert Ok(val) = smut.new(global_smut_table, 0)
let assert Ok(x) = smut.get(val)
echo x
// 0
smut.set(3, val)
// We sleep for a second here to give the write-governing process time
// to make its update before reading back.
process.sleep(100)
let assert Ok(x) = smut.get(val)
echo x
// 3
let assert Ok(x) = smut.update_and_get(
fn(n) { n * 4 },
val
)
echo x
// 12
let assert Ok(x) = smut.get_and_update(
fn(n) { n - 3 },
val
)
echo x
// 12
let assert Ok(x) = smut.get(val)
echo x
// 9
}