This is the first time I hear about NonCancellable context even though I've been working with coroutines for about 2 years! This sure comes in handy in large-scale apps, thank you :)
Bin ja eh ein riesen Fan von deinem Kanal und deine Canvas und Testing Kurse haben mir richtig gut gefallen. Auch dieses Video hat mir wieder weitergeholfen und kam on-Point. Nachdem deine Zielgruppe ja vom Anfänger bis zum ambitionierten fortgeschritten Entwickler ist, würde ich mich auch sehr über Videos zum Thema Performance Analyse und Verbesserung, ebenso wie Memory Management freuen. Übrigens deine Idee eines neuen Kotlin Types der einen private setter und public getter built-in hat (aufgeschnappt in einem Podcast mit deiner Beteiligung) hab ich mir auch schon länger gewünscht. So spart man sich einfach diese ewige Redundanz im ViewModel 👍
Hi Philipp, Could you make a video about coroutine backpressure. And how we could slow down the producer if the consumer cannot process all events. In RxJava this was easy thanks to the "request" method in Subscription, but in Flow it is not clear how this connection can be organized.
before rethrowing CE you better check if the coroutine isActive. you might get CE not from cancellation process, which is probably a bug somewhere down the callstack but you'll just rethrow it, and it'll silently kill your parent coroutine
In the #2 mistake: shouldn't the api.saveNote() call be also in the withContext block? What if the api call finishes and right away the coroutine is cancelled before it reaches the NonCancellable block?
Also at a trap 3 i guess, we could let the file be readed completely, but right after reading make ensureActive(), but because of we need to return it from lambda we can do something like: it.readBytes().apply{ensureActive()}. Then after reading file if we cancelled the coroutine it will not go further because of thrown CancellationException, which will propagade up to the launch coroutine
@@PhilippLackner Maybe i found a solution, which will 1) not require decomposition of non-suspend time-demanding function. 2) Will not break Cooperative cancellation and Structured Concurrency. Of course, we cannot cancel such a function, because cancellation is just an Exception which is being raised by delay() for example. But, what if we call this function in the independant CoroutineScope Job, and join() it in our main Job? Then, it obviously will not stop and go on with reading file, BUT our coroutine will stop, because the join() function has it's own suspension and will raise own CancellationException when cancel(). If summarize, our non-suspend time-consuming function will work in a "hidden scope", which doesn't take part in the "Coroutine Tree", and in our Job we just launch it in this scope and join(). Then, if not cancelled - then all ok, this function will finish work, then our join() will stop waiting and Job will be Completed. If cancelled, it firstly will cancel all it's children, so there is all ok, but then in will cancel itself and become again Completed. So, parent coroutine will be notified about cancellation. And if we wish return something, then just replace join() and launch() with await() and async(). Thanks for reading a lot xD
The Coroutine cancellableException is very troublesome and tricky :( The thing is that coroutines will be "really" cancelled when they meet other suspension point after cancelling.
I have a doubt in Note example, when saving Note (isSynched=false) then Api call and then by using Upsert function (isSynched = true) you updated same note.. but after first insert Note is added to database with autoincrememted id, how you update same note without updating id in note object?
Because that is just a sample, the main focus of the topic is not about Room and how to update data instead it focuses on how to handle cancellation scenario properly in Coroutine. What is being show is like a pseudo code for you to have clearer idea of the scenario.
@@bitwisedevs469 Ohh.. ohk.. I always have to work with Room database in my company.. So that's why I was curious if there is shortcut to update database using UPSERT function. Thanks for info
@@Sandy-dz6qz Hi, Actually I have a doubt, in one of the scenario I was using insert annotation to insert the newly entered notes and I had set id to auto increment and if the id is already present then it should ignore that as i had used onconflict strategy replace. But it is always inserting new row no matter it is already present or not. Do you have any idea why it is happening?
@@santoshbhatt6924 When inserting Notes into database you have to get Id of that perticular row first and need to set that id to Notes object and then fire a query with same id.. then onconflict strategy will work