-
Notifications
You must be signed in to change notification settings - Fork 437
/
example-stm-02.kt
47 lines (42 loc) · 1.44 KB
/
example-stm-02.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// This file was automatically generated from STM.kt by Knit tool. Do not edit.
package arrow.fx.stm.examples.exampleStm02
import arrow.fx.stm.atomically
import arrow.fx.stm.TVar
import arrow.fx.stm.STM
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
fun STM.transfer(from: TVar<Int>, to: TVar<Int>, amount: Int): Unit {
withdraw(from, amount)
deposit(to, amount)
}
fun STM.deposit(acc: TVar<Int>, amount: Int): Unit {
val current = acc.read()
acc.write(current + amount)
// or the shorthand acc.modify { it + amount }
}
fun STM.withdraw(acc: TVar<Int>, amount: Int): Unit {
val current = acc.read()
if (current - amount >= 0) acc.write(current - amount)
else retry() // we now retry if there is not enough money in the account
// this can also be achieved by using `check(current - amount >= 0); acc.write(it + amount)`
}
fun main(): Unit = runBlocking {
val acc1 = TVar.new(0)
val acc2 = TVar.new(300)
println("Balance account 1: ${acc1.unsafeRead()}")
println("Balance account 2: ${acc2.unsafeRead()}")
async {
println("Sending money - Searching")
delay(2000)
println("Sending money - Found some")
atomically { acc1.write(100_000_000) }
}
println("Performing transaction")
atomically {
println("Trying to transfer")
transfer(acc1, acc2, 50)
}
println("Balance account 1: ${acc1.unsafeRead()}")
println("Balance account 2: ${acc2.unsafeRead()}")
}