@@ -41,6 +41,16 @@ import java.time.Instant
4141 * and request they start their counterpart flow, then make sure it's annotated with [InitiatingFlow]. This annotation
4242 * also has a version property to allow you to version your flow and enables a node to restrict support for the flow to
4343 * that particular version.
44+ *
45+ * Functions that suspend the flow (including all functions on [FlowSession]) accept a [maySkipCheckpoint] parameter
46+ * defaulting to false, false meaning a checkpoint should always be created on suspend. This parameter may be set to
47+ * true which allows the implementation to potentially optimise away the checkpoint, saving a roundtrip to the database.
48+ *
49+ * This option however comes with a big warning sign: Setting the parameter to true requires the flow's code to be
50+ * replayable from the previous checkpoint (or start of flow) up until the next checkpoint (or end of flow) in order to
51+ * prepare for hard failures. As suspending functions always commit the flow's database transaction regardless of this
52+ * parameter the flow must be prepared for scenarios where a previous running of the flow *already committed its
53+ * relevant database transactions*. Only set this option to true if you know what you're doing.
4454 */
4555abstract class FlowLogic <out T > {
4656 /* * This is where you should log things to. */
@@ -123,7 +133,7 @@ abstract class FlowLogic<out T> {
123133 */
124134 @Deprecated(" Use FlowSession.getFlowInfo()" , level = DeprecationLevel .WARNING )
125135 @Suspendable
126- fun getFlowInfo (otherParty : Party ): FlowInfo = stateMachine.getFlowInfo(otherParty, flowUsedForSessions)
136+ fun getFlowInfo (otherParty : Party ): FlowInfo = stateMachine.getFlowInfo(otherParty, flowUsedForSessions, maySkipCheckpoint = false )
127137
128138 /* *
129139 * Serializes and queues the given [payload] object for sending to the [otherParty]. Suspends until a response
@@ -157,7 +167,7 @@ abstract class FlowLogic<out T> {
157167 @Deprecated(" Use FlowSession.sendAndReceive()" , level = DeprecationLevel .WARNING )
158168 @Suspendable
159169 open fun <R : Any > sendAndReceive (receiveType : Class <R >, otherParty : Party , payload : Any ): UntrustworthyData <R > {
160- return stateMachine.sendAndReceive(receiveType, otherParty, payload, flowUsedForSessions)
170+ return stateMachine.sendAndReceive(receiveType, otherParty, payload, flowUsedForSessions, retrySend = false , maySkipCheckpoint = false )
161171 }
162172
163173 /* *
@@ -171,17 +181,17 @@ abstract class FlowLogic<out T> {
171181 */
172182 @Deprecated(" Use FlowSession.sendAndReceiveWithRetry()" , level = DeprecationLevel .WARNING )
173183 internal inline fun <reified R : Any > sendAndReceiveWithRetry (otherParty : Party , payload : Any ): UntrustworthyData <R > {
174- return stateMachine.sendAndReceive(R ::class .java, otherParty, payload, flowUsedForSessions, retrySend = true )
184+ return stateMachine.sendAndReceive(R ::class .java, otherParty, payload, flowUsedForSessions, retrySend = true , maySkipCheckpoint = false )
175185 }
176186
177187 @Suspendable
178188 internal fun <R : Any > FlowSession.sendAndReceiveWithRetry (receiveType : Class <R >, payload : Any ): UntrustworthyData <R > {
179- return stateMachine.sendAndReceive(receiveType, counterparty, payload, flowUsedForSessions, retrySend = true )
189+ return stateMachine.sendAndReceive(receiveType, counterparty, payload, flowUsedForSessions, retrySend = true , maySkipCheckpoint = false )
180190 }
181191
182192 @Suspendable
183193 internal inline fun <reified R : Any > FlowSession.sendAndReceiveWithRetry (payload : Any ): UntrustworthyData <R > {
184- return stateMachine.sendAndReceive(R ::class .java, counterparty, payload, flowUsedForSessions, retrySend = true )
194+ return stateMachine.sendAndReceive(R ::class .java, counterparty, payload, flowUsedForSessions, retrySend = true , maySkipCheckpoint = false )
185195 }
186196
187197 /* *
@@ -206,7 +216,7 @@ abstract class FlowLogic<out T> {
206216 @Deprecated(" Use FlowSession.receive()" , level = DeprecationLevel .WARNING )
207217 @Suspendable
208218 open fun <R : Any > receive (receiveType : Class <R >, otherParty : Party ): UntrustworthyData <R > {
209- return stateMachine.receive(receiveType, otherParty, flowUsedForSessions)
219+ return stateMachine.receive(receiveType, otherParty, flowUsedForSessions, maySkipCheckpoint = false )
210220 }
211221
212222 /* * Suspends until a message has been received for each session in the specified [sessions].
@@ -250,7 +260,9 @@ abstract class FlowLogic<out T> {
250260 */
251261 @Deprecated(" Use FlowSession.send()" , level = DeprecationLevel .WARNING )
252262 @Suspendable
253- open fun send (otherParty : Party , payload : Any ) = stateMachine.send(otherParty, payload, flowUsedForSessions)
263+ open fun send (otherParty : Party , payload : Any ) {
264+ stateMachine.send(otherParty, payload, flowUsedForSessions, maySkipCheckpoint = false )
265+ }
254266
255267 /* *
256268 * Invokes the given subflow. This function returns once the subflow completes successfully with the result
@@ -342,7 +354,10 @@ abstract class FlowLogic<out T> {
342354 * valid by the local node, but that doesn't imply the vault will consider it relevant.
343355 */
344356 @Suspendable
345- fun waitForLedgerCommit (hash : SecureHash ): SignedTransaction = stateMachine.waitForLedgerCommit(hash, this )
357+ @JvmOverloads
358+ fun waitForLedgerCommit (hash : SecureHash , maySkipCheckpoint : Boolean = false): SignedTransaction {
359+ return stateMachine.waitForLedgerCommit(hash, this , maySkipCheckpoint = maySkipCheckpoint)
360+ }
346361
347362 /* *
348363 * Returns a shallow copy of the Quasar stack frames at the time of call to [flowStackSnapshot]. Use this to inspect
0 commit comments