Skip to content

Commit

Permalink
FallibleBook can fail first, but succeed after rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
odipar committed Dec 5, 2021
1 parent 219f327 commit 17cdb97
Showing 1 changed file with 34 additions and 18 deletions.
52 changes: 34 additions & 18 deletions src/main/scala/org/jmanikin/scala/example/bank/Bank.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,34 @@ object Bank {
}

case class TransferId(id: Long) extends Id[Transfer] { def init = Transfer() }
case class Transfer(from: AccountId = null, to: AccountId = null, amount: Double = 0.0)
case class Transfer(from: AccountId = null, to: AccountId = null, amount: Double = 0.0, failed: Boolean = false)
trait TransferMsg extends ScalaMessage[TransferId, Transfer, Unit]

case class Book(from: AccountId, to: AccountId, amount: Double) extends TransferMsg {
case class FallibleBook(from: AccountId, to: AccountId, amount: Double) extends TransferMsg {
def scala =
pre { amount > 0.0 && from != to }.
app { Transfer(from, to, amount) }.
eff { send(from, Withdraw(amount)); send(to, Deposit(amount)) }.
eff {
try { send(self, ApplyBook(from, to, amount)) }
catch { case e: Throwable => send(self, FailBook(e)) }
}.
pst { obj(from).balance + obj(to).balance == old(from).balance + old(to).balance }

private case class ApplyBook(from: AccountId, to: AccountId, amount: Double) extends TransferMsg {
def scala =
pre { true }.
app { obj }.
eff { send(to, Deposit(amount)) ; send(from, Withdraw(amount)) }.
pst { true }
}

private case class FailBook(e: Throwable) extends TransferMsg {
def scala =
pre { obj.from != null && obj.to != null && !obj.failed }.
app { obj.copy(failed = true) }.
eff { }.
pst { obj.failed }
}
}

def main(args: Array[String]): Unit = {
Expand All @@ -54,27 +73,24 @@ object Bank {
val t2 = TransferId(2)

try {
val w1 = EventWorld().
send(a1, Open(50)).world

val w2 = EventWorld().
val w1 = EventWorld().
send(a1, Open(50)).
send(a2, Open(80)).world

val w3 = w2 merge w1

val w4 = w3.
send(t1, Book(a1, a2, 30)).
world
val w2 = w1.
send(t1, FallibleBook(a1, a2, 60)).world

val w5 = w3.
send(t2, Book(a1, a2, 20)).
world
val w3 = w1.
send(t2, FallibleBook(a2, a1, 30)).world

val w6 = w5 rebase w4
val w4 = w2.rebase(w3)

println(w6)
println(w6.obj(a1).value.balance) // 0.0
println(w6.obj(a2).value.balance) // 130.0
println("w2:\n" + w2)
println("w3:\n" + w3)
println("w4:\n" + w4)
println(w4.obj(a1).value.balance)
println(w4.obj(a2).value.balance)
}
catch {
case e: WorldErr => println(e)
Expand Down

0 comments on commit 17cdb97

Please sign in to comment.