maxmello
09/18/2024, 1:48 PM.onEach
running (handling rabbitMQ messages). This flow should never complete/stop, except when the whole application goes down. Therefore, I have the inside of the .onEach
wrapped by a try-catch
block with catching e: Exception
.
Inside this code block, I run code that includes Exposed suspended transactions. It can happen that I get expected SQL exceptions, which I also catch, but somehow I always get
kotlinx.coroutines.JobCancellationException: Parent job is Cancelling
Caused by: org.jetbrains.exposed.exceptions.ExposedSQLException
As stated, this exception is catched though, but the flow still completes. So I can only imagine that some code (maybe Exposed code) manually cancels the parent job, right?phldavies
09/18/2024, 1:58 PMsupervisorScope
as any child coroutines that fail will propagate that failure to the parent scope and cause cancellation to propagate otherwisegildor
09/19/2024, 2:22 AMmaxmello
09/19/2024, 9:45 AMinsertIntoDatabase
call in the snippet below in supervisorScope { … }
did fix the problem.
As I realize I am no coroutine expert, I’m not fully sure why, maybe the TransactionScope
using the parent coroutine context as its own coroutine context means, its the Flow
s coroutine context that is cancelled when an exception inside the suspendedTransaction
block occurs?phldavies
09/19/2024, 11:09 AMCancellationException
without rethrowing it as doing so will break structured concurrency. If a coroutine fails (that is, throws a non-cancellation exception) then normally the parent coroutine will fail itself and propagate its cancellation to its remaining children. supervisorScope
handles child-failure by effectively ignoring it - meaning it will not fail itself when a child failsmaxmello
09/19/2024, 11:33 AMnewSuspendedTransaction
takes CoroutineContext? = null
as a first optional parameter. When I call newSuspendedTransaction(<http://Dispatchers.IO|Dispatchers.IO>)
, it behaves identical to when I wrap the code in supervisorScope
. So I think the problem was that the TA took the flows coroutine context as its own context, which then cancelled the whole flow on failure of the transaction