Can function of DAO class be called in ViewModel class without Coroutine - kotlin

All the queries to the database are written in CouroutineScope. But this line of code in just inside of ViewModel class. And it's not blocking the UI thread. I don't understand how is it executing
private val nights = database.getAllNights()
You can see the whole repo in this link

The Dao function getAllNights() is returning a LiveData:
fun getAllNights(): LiveData<List<SleepNight>>
This return is done immediately upon calling that function, without waiting for the results to load from the database. The LiveData can then be observed to be notified when the data is loaded (on a background thread, asynchronously). It will also notify observers if the result of the query changes later on.
In contrast, if you take one of the calls where it's wrapped inside a launch and a switch to the IO dispatcher, such as getTonight():
fun getTonight(): SleepNight?
A Dao function like this will block the thread until it gets the result of the query, which is why it's important that you take care of going to a background thread before calling it.

Related

Kotlin + Arrow-kt - why are my coroutines not cancelling properly?

I am using Kotlin together with Arrow-Kt libraries.
I am launching on a specific scope some coroutines that make use of Arrow-kt's Schedule.
At a certain time, I want to be able to cancel all those coroutines that were launched on that scope, but after I cancel the scope basically nothing changes and whatever was running on the Schedule, continues to run, which is not what I wanted.
I already tried to place some yield() calls to force the coroutines to be cancellable, but the behavior didn't change.
Here is the code:
Main function doing the launches:
private val ballFetchingScope= CoroutineScope(CoroutineName("ball-fetching"))
fun fetchBalls(periodicity: Periodicity) {
val balls = stockRepository.getAllBalls() //basically a list of different balls
balls.forEach {
ballFetchingScope.launch(Dispatchers.IO) { ballFetcher.startFetching(it, periodicity) }
}
}
startFetching function, using Arrow-kt's schedule:
suspend fun startFetching(ball: Ball, periodicity: Periodicity) {
Schedule.forever<Unit>()
.and(Schedule.spaced(periodicity))
.repeat {
yield()
//ball fetching logic here
}
}
Expected behavior:
When calling ballFetchingScope.cancel() all coroutines are cancelled and all fetching stops.
Ideally not even needing to wait until it reaches the yield() call, if it is waiting for the next run to happen, I would like for it to cancel and not even start a new run of the repeat block.
What is actually happening:
Fetching continues to happen normally.
It's a bit hard to say here what is going on.
It's very strange that this is not working for you, since Schedule relies on KotlinX kotlin.coroutines.delay to execute the Schedule.spaced. So it should get cancelled while waiting for the next run.
It also checks coroutineContext.ensureActive() before running the function passed to repeat so it also automatically check in the place where you now manually placed yield.
Which version of Arrow are you using? And could you share a fully reproducible example?
I am answering my own post just to make sure you are not making the same dumb mistake I was making.
Everything was working as supposed, the issue was on my side.
I had two different instances of the class containing the ballFetchingScope
This means that I was calling the ballFetchingScope.cancel() on the scope for one of those instances while the Coroutines were running on the scope in the other instance.
Botom-line: Make sure you are not using multiple instances when you think you have only one.

Should I use synchronous Mono::map or asycnhronous Mono::flatMap?

The projectReactor documentation says that Mono::flatMap is asynchronous, as shown below.
So, I can write all my methods to return Mono publishers like this.
public Mono<String> myMethod(String name) {
return Mono.just("hello " + name);
}
and use it with Mono::flatMap like this:
Mono.just("name").flatMap(this::myMethod);
Does this make the execution of my method asynchronous? Does this make my code more reactive, better and faster than just using Mono::map? Is the overhead prohibitive for doing this for all my methods?
public final Mono flatMap(Function<? super T,? extends Mono<? extends R>> transformer)
Transform the item emitted by this Mono asynchronously, returning the value emitted by another Mono (possibly changing the value type).
Does this make the execution of my method asynchronous?
Let's go to the definition of Asynchronous for this:
Asynchronous programming is a means of parallel programming in which a unit of work runs separately from the main application thread and notifies the calling thread of its completion, failure or progress.
Here your unit of work is happening in the same thread, unless you do a subscribeOn with a Scheduler. So this isn't async.
Does this make my code more reactive, better and faster than just using Mono::map?
No way. Since in this case, the publisher Mono.just("hello " + name) immediately notifies the subscriber that I am done, the thread in which the processing was going on immediately picks up that event from the event loop and starts processing the response.
Rather, this might cause few more operations internally than a map which simply transforms the element.
Thus, ideally, you should use a flatMap when you have an I/O Operation (like DB calls) or Network calls, which might take some time, which you can utilize in doing some other task , if all the threads are busy.

Do I have to check the InvokeRequired and use the Invoke function with every control I want to update?

I'm writing a scheduler. It has a single form frmMain, which shows jobs that are currently running, and a history of job steps that have run. It has an object of class Scheduler that manages running new jobs. Scheduler keeps a collection class, List which contains objects of class RunningJob. RunningJob executes each step in turn through a series of sub-classes.
When a job is started, the Scheduler creates a new BackgroundWorker with the DoWork, ProgressChanged and RunWorkerCompleted methods setup with handlers that point back into the instance of RunningJob.
Each time a job/step starts/ends, one of these handers in RunningJob raises an appropriate event into Scheduler and Scheduler raises an appropriate event into frmMain. i.e.:
frmMain (1 instance) <---- Scheduler (1 instance) <---- RunningJob.WorkerProgressChanged (many instances)
The RunningJob executes correctly, but the reporting going up to the interface is not working correctly. Also any logging to files I do is suspect (I'm using a single function: LogInfo to do this). I have a number of questions:
When I use InvokeRequired() and Invoke() within frmMain, do I have to do this with every single control I want to update (there are several). Can I just check InvokeRequired() on one control and use Invoke on all of them based on that result.
Why bother checking InvokeRequired() at all and just use Invoke() every single time? It will make for simpler code.
There is only one instance of Scheduler and I am raising events to get execution back into it from each Job. I think this is part of the problem. How is multithreading handled doing this? Is there some sort of InvokeRequired/Invoke check I can do on the events before raising them? Can I raise events at all in this situation? I like events, rather than calling methods on the owner class, because it improves encapsulation. What is best practice here?
In general, if I'm calling a piece of code from many different threads, not necessarily to update a form, but just to perform some function (e.g. add a line of text to a file for logging purposes), how do I block one thread until the other has completed?

How to get current `coroutineContext` from a non-suspend function?

Say I have a logging function:
fun log(message: String)
Unfortunately, this function will be called both from coroutines and outside of coroutines. In case of coroutines, I would like to log additional information coming from coroutine context (for example, coroutine's name).
How can I achieve this?
These are my thoughts but I don't have a solution:
Somehow figure out inside log if it is inside a coroutine and get coroutineContext. Is this possible?
I could have two versions of log e.g. log and logSuspend. But how do I ensure the right one gets called? If I'm inside suspend, nothing prevents me from calling log by accident. Additionally, I may have a regular helper function. Which one should it call?
Maybe something with ThreadLocal, for example I could coroutineContext inside a ThreadLocal at some point, but how do I ensure it stays up to date?
Somehow figure out inside log if it is inside a coroutine and get
coroutineContext. Is this possible?
I don't think there is a good solution for that.
I would create two log functions, first for general purpose, second - an extension function on CoroutineScope for coroutines:
fun log(message: String) {...}
fun CoroutineScope.log(message: String) {
//here you can access coroutineContext
}
And if you call log function from the coroutine like this:
GlobalScope.launch {
log("CoroutineScope.log")
}
the extension function will be called and you will have access to coroutineContext.
Note: GlobalScope is not recommended to use, it is just for demonstration purposes.

Suitable pattern for updating a progress bar from multiple threads (using TPL?)

I've been busy updating my brain with the TPL because I intend on using it for my new application (which uses .Net Framework 4.0). However I have some doubts that someone might clarify for me. Previously, I had a progress form which I would launch from the main (GUI) thread after I started the thread which needed to display its' progress. It looked something like this:
sortThread = New Thread(AddressOf _Sorter.Sort())
_ProgressForm = New FrmProgress()
_Sorter.ProgressForm = _ProgressForm
sortThread.Start()
progressForm.ShowDialog()
Basically it would initialize the thread, initialize a FrmProgress form object and assign it to the Sorter object which would then update the progress form (which contained a progress bar and some labels) from its Sort() sub on the separate thread. Updating these control properties was achieved by checking the InvokeRequired property of the FrmProgress form and if needed it would then use the Invoke() method of the control that was to be updated... ex:
Public Sub IncrementProgressBar(x As Integer)
If Me.InvokeRequired Then
pb_MainProgressBar.Invoke(Sub() IncrementProgressBar(x))
Else
pb_MainProgressBar.Increment(x)
End If
End Sub
Now I am interested in using TPL to launch separate worker threads (multiple) that may want to update the progress bar. Should I use the same pattern or should I consider accessing a public TaskScheduler.FromCurrentSynchronizationContext context that was obtained in the main GUI thread? In both cases I suppose I should provide some kind of locking mechanism on the form (SyncLock?)
Invoke should be sufficient, as you are doing. If two different threads try to invoke in parallel the first one will execute first, then the second when the UI thread becomes free. The UI thread cannot service two invokes simultaneously - they are naturally handled in FIFO sequence so there is no issue with thread safety. Any number of threads can invoke on the main thread without worrying about each other or using any additional locking mechanism.
Note, however, that any thread calling Invoke will block until the main thread can service the call. If you, for example, had many threads invoking heavy code at the same time then your various threads would block on the invoke calls until they got their kick at the can, so to speak. If you use BeginInvoke then the calling thread will simply continue executing and the invoked method will be placed in the UI thread's queue (which it will service as soon as it can).