问题
I understand there's some annotation related to @Suspendable
to mark a function as serialisable. How much does a flow checkpoint itself?
Does a node checkpoint itself only when there's a send
/sendAndReceive
when it waits for a response? Or does it serialise checkpoints at an interval?
Given a flow that does nothing but computation, how much does it serialise/write to disk, and does this affect performance if there's a peak load of read/write from other thread doing vault queries/writing.
How does @Suspendable
play a part in the these private methods that just do computation and nothing else. If a method gets annotated, it will only get serialise on the next send
else nothing gets serialised?
Example
@Suspendable
override fun call() {
val states = querySomeStates()
computeSomethingHeavy(states)
decideSomething()
}
@Suspendable
private querySomeStates()
@Suspendable
computeSomethingHeavy()
@Suspendable
decideSomething()
回答1:
@Suspendable
marks a function as potentially suspendable. The flow is actually suspended only when one of the following operations is performed:
- Flow start
send
receive
sendAndReceive
waitForLedgerCommit
getFlowInfo
sleep
When one of these operations is performed, the node uses Quasar to capture the execution stack and create a checkpoint. If a function does not perform any of these operations, no checkpoints will be created. This is true even if the flow is doing heavy computation and/or the function is marked @Suspendable
. In other words, Quasar does not do preemption, meaning we don't "checkpoint periodically", but only at specific call sites.
For example, here is the sequence of checkpoints in a simple flow:
@Suspendable
fun call() {
// checkpoint!
sendSomething()
computeSomething()
}
@Suspendable
fun sendSomething() {
send() // checkpoint!
}
@Suspendable
fun computeSomething() {
heavyComputation() // no checkpoint!
}
来源:https://stackoverflow.com/questions/51178007/when-does-a-node-checkpoint-itself