aboutsummaryrefslogtreecommitdiff
path: root/doc_test.go
diff options
context:
space:
mode:
authorMatt Joiner <anacrolix@gmail.com>2021-08-24 21:57:45 +1000
committerMatt Joiner <anacrolix@gmail.com>2021-08-24 21:57:45 +1000
commit19167a61a2c57caeda2eb7ce787c12e79d20c9ac (patch)
treeeb0fd307a670b1e0f79c45667b479957207138d5 /doc_test.go
parentUpdate reference badge (diff)
downloadstm-19167a61a2c57caeda2eb7ce787c12e79d20c9ac.tar.gz
stm-19167a61a2c57caeda2eb7ce787c12e79d20c9ac.tar.xz
Create package-level example doc test from README
This should synchronize the examples more with the actual API by actually running them.
Diffstat (limited to 'doc_test.go')
-rw-r--r--doc_test.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/doc_test.go b/doc_test.go
new file mode 100644
index 0000000..f6bb863
--- /dev/null
+++ b/doc_test.go
@@ -0,0 +1,77 @@
+package stm_test
+
+import (
+ "github.com/anacrolix/stm"
+)
+
+func Example() {
+ // create a shared variable
+ n := stm.NewVar(3)
+
+ // read a variable
+ var v int
+ stm.Atomically(stm.VoidOperation(func(tx *stm.Tx) {
+ v = tx.Get(n).(int)
+ }))
+ // or:
+ v = stm.AtomicGet(n).(int)
+ _ = v
+
+ // write to a variable
+ stm.Atomically(stm.VoidOperation(func(tx *stm.Tx) {
+ tx.Set(n, 12)
+ }))
+ // or:
+ stm.AtomicSet(n, 12)
+
+ // update a variable
+ stm.Atomically(stm.VoidOperation(func(tx *stm.Tx) {
+ cur := tx.Get(n).(int)
+ tx.Set(n, cur-1)
+ }))
+
+ // block until a condition is met
+ stm.Atomically(stm.VoidOperation(func(tx *stm.Tx) {
+ cur := tx.Get(n).(int)
+ if cur != 0 {
+ tx.Retry()
+ }
+ tx.Set(n, 10)
+ }))
+ // or:
+ stm.Atomically(stm.VoidOperation(func(tx *stm.Tx) {
+ cur := tx.Get(n).(int)
+ tx.Assert(cur == 0)
+ tx.Set(n, 10)
+ }))
+
+ // select among multiple (potentially blocking) transactions
+ stm.Atomically(stm.Select(
+ // this function blocks forever, so it will be skipped
+ stm.VoidOperation(func(tx *stm.Tx) { tx.Retry() }),
+
+ // this function will always succeed without blocking
+ stm.VoidOperation(func(tx *stm.Tx) { tx.Set(n, 10) }),
+
+ // this function will never run, because the previous
+ // function succeeded
+ stm.VoidOperation(func(tx *stm.Tx) { tx.Set(n, 11) }),
+ ))
+
+ // since Select is a normal transaction, if the entire select retries
+ // (blocks), it will be retried as a whole:
+ x := 0
+ stm.Atomically(stm.Select(
+ // this function will run twice, and succeed the second time
+ stm.VoidOperation(func(tx *stm.Tx) { tx.Assert(x == 1) }),
+
+ // this function will run once
+ stm.VoidOperation(func(tx *stm.Tx) {
+ x = 1
+ tx.Retry()
+ }),
+ ))
+ // But wait! Transactions are only retried when one of the Vars they read is
+ // updated. Since x isn't a stm Var, this code will actually block forever --
+ // but you get the idea.
+}