Difference between ExecutorCoroutineDispatcher and CoroutineDispatcher - dispatcher

Can someone please explain the difference between Kotlin Coroutine's ExecutorCoroutineDispatcher and CoroutineDispatcher from practical point of view, i.e. in which scenarios to use one against another?
So far I've been using Dispatchers, but (as far as I see) it can't give me a single background thread. That's the reason I'm using newSingleThreadExecutor().
What I've noticed though is that my main process never ends while using ExecutorCoroutineDispatcher (1) (with CoroutineDispatcher it finished as expected (2)). After some investigation it appears that I should run method close() on ExecutorCoroutineDispatcher for the main process to be finished (3). With CoroutineDispatcher you don't have to do this, it doesn't even have method close() (4).
Is CoroutineDispatcher closed automatically? Why do we have closure process for ExecutorCoroutineDispatcher, but not for CoroutineDispatcher?
Below is a code I've used for testing:
fun main() = runBlocking<Unit> {
val dispatcher1 = Executors.newSingleThreadExecutor().asCoroutineDispatcher() // (1) <-- main process runs indefinitely w/o closing dispatcher1 (3)
val dispatcher2 = Dispatchers.Unconfined // (2)
println("Start")
launch(dispatcher1) {
println("Child")
delay(1000)
printInfo(coroutineContext, this)
}.join()
println("End")
dispatcher1.close() // (3) <-- need to close dispatcher1 for the main process to finish, otherwise it runs indefinitely
// dispatcher2.close() // (4) <-- dispatcher2 doesn't have method 'close()'
}

Is CoroutineDispatcher closed automatically? Why do we have closure process for ExecutorCoroutineDispatcher, but not for CoroutineDispatcher?
The difference is not in the dispatcher type, but in how the underlying Java Executor Service is configured. The default shared executors use daemon threads, which don't prevent the JVM from shutting down. If you want to, you can get the same for your own executors:
val myExecutor = Executors.newSingleThreadExecutor { task ->
Thread(task).also { it.isDaemon = true }
}
val myDispatcher = myExecutor.asCoroutineDispatcher()
suspend fun main() {
withContext(myDispatcher) {
println("On my dispatcher")
}
}

Related

C++ How to know that a thread launched with std::async is running?

In my application I have a callback and, if a certain event happens, it has to perform certain operations.
void callback()
{
if(event == true)
{
// long processing
performOperations();
}
}
Now, the thing is that the callback is called at a 30Hz rate, while the performOperations function can take also ~10 seconds to complete.
After a quick search online I came across std::async. The strategy I want to implement is that if the performOperations is running and a new event
happens I want to "kill" (stop nicely) the running thread and start a new one which still launches the performOperations function.
So, something like this:
void callback()
{
if(event == true)
{
// check if there's a running thread
if(already_running == true)
{
// stop nicely the running thread
...
}
// long processing
performOperations();
}
}
Therefore, my question. Is there a way to know that performOperations is still running and kill it?
Thanks

Ensuring that only one instance of a function is running?

I'm just getting into concurrent programming. Most probably my issue is very common, but since I can't find a good name for it, I can't google it.
I have a C++ UWP application where I try to apply MVVM pattern, but I guess that the pattern or even being UWP is not relevant.
First, I have a service interface that exposes an operation:
struct IService
{
virtual task<int> Operation() = 0;
};
Of course, I provide a concrete implementation, but it is not relevant for this discussion. The operation is potentially long-running: it makes an HTTP request.
Then I have a class that uses the service (again, irrelevant details omitted):
class ViewModel
{
unique_ptr<IService> service;
public:
task<void> Refresh();
};
I use coroutines:
task<void> ViewModel::Refresh()
{
auto result = co_await service->Operation();
// use result to update UI
}
The Refresh function is invoked on timer every minute, or in response to a user request. What I want is: if a Refresh operation is already in progress when a new one is started or requested, then abandon the second one and just wait for the first one to finish (or time out). In other words, I don't want to queue all the calls to Refresh - if a call is already in progress, I prefer to skip a call until the next timer tick.
My attempt (probably very naive) was:
mutex refresh;
task<void> ViewModel::Refresh()
{
unique_lock<mutex> lock(refresh, try_to_lock);
if (!lock)
{
// lock.release(); commented out as harmless but useless => irrelevant
co_return;
}
auto result = co_await service->Operation();
// use result to update UI
}
Edit after the original post: I commented out the line in the code snippet above, as it makes no difference. The issue is still the same.
But of course an assertion fails: unlock of unowned mutex. I guess that the problem is the unlock of mutex by unique_lock destructor, which happens in the continuation of the coroutine and on a different thread (other than the one it was originally locked on).
Using Visual C++ 2017.
use std::atomic_bool:
std::atomic_bool isRunning = false;
if (isRunning.exchange(true, std::memory_order_acq_rel) == false){
try{
auto result = co_await Refresh();
isRunning.store(false, std::memory_order_release);
//use result
}
catch(...){
isRunning.store(false, std::memory_order_release);
throw;
}
}
Two possible improvements : wrap isRunning.store in a RAII class and use std::shared_ptr<std::atomic_bool> if the lifetime if the atomic_bool is scoped.

Usage of worker threads in MFC

//Case I : ( It works but not sure if it is safe . Is it because the windows
messages are handle in a process queue already? )
void MyDlg::OnClickButton1()
{
std::thread([]()
{
// some long computation here
SetDlgItemText(IDC_STATIC_TEXT, L"Updated");
}).detach();
}
//Case II : ( It works . But is the process_queue redundant )
void MyDlg::OnClickButton1()
{
std::thread([]()
{
// some long computation here
command_node node =
command_factory("SetDlgItemText",IDC_STATIC_TEXT, "Updated");
SendMessageToMyProcessQueue(node);
}).detach();
}
void MyDlg::OnPaint()
{
ExecuteFromMyProcessQueue();
CDialogEx::OnPaint();
}
This is a sample snippet in VC++ using MFC and I want to use a worker thread to complete a task and send the result to a control. Which on is desirable or any other work around?
It is generally a good idea (or required) to refrain from accessing the GUI directly from other threads than the main thread. MFC might assert or it might not, depending on how consistent it is implemented. See also this answer. So that rules out your first case.
Using message queues is the safe and correct way to do it. See also this thread on how to update the UI from another thread.

RxCpp: observer's lifetime if using observe_on(rxcpp::observe_on_new_thread())

What is the proper way to wait until all the observers on_completed are called if the observers are using observe_on(rxcpp::observe_on_new_thread()):
For example:
{
Foo foo;
auto generator = [&](rxcpp::subscriber<int> s)
{
s.on_next(1);
// ...
s.on_completed();
};
auto values = rxcpp::observable<>::create<int>(generator).publish();
auto s1 = values.observe_on(rxcpp::observe_on_new_thread())
.subscribe([&](int) { slow_function(foo); }));
auto lifetime = rxcpp::composite_subscription();
lifetime.add([&](){ wrapper.log("unsubscribe"); });
auto s2 = values.ref_count().as_blocking().subscribe(lifetime);
// hope to call something here to wait for the completion of
// s1's on_completed function
}
// the program usually crashes here when foo goes out of scope because
// the slow_function(foo) is still working on foo. I also noticed that
// s1's on_completed never got called.
My question is how to wait until s1's on_completed is finished without having to set and poll some variables.
The motivation of using observe_on() is because there are usually multiple observers on values, and I would like each observer to run concurrently. Perhaps there are different ways to achieve the same goal, I am open to all your suggestions.
Merging the two will allow a single blocking subscribe to wait for both to finish.
{
Foo foo;
auto generator = [&](rxcpp::subscriber<int> s)
{
s.on_next(1);
s.on_next(2);
// ...
s.on_completed();
};
auto values = rxcpp::observable<>::create<int>(generator).publish();
auto work = values.
observe_on(rxcpp::observe_on_new_thread()).
tap([&](int c) {
slow_function(foo);
}).
finally([](){printf("s1 completed\n");}).
as_dynamic();
auto start = values.
ref_count().
finally([](){printf("s2 completed\n");}).
as_dynamic();
// wait for all to finish
rxcpp::observable<>::from(work, start).
merge(rxcpp::observe_on_new_thread()).
as_blocking().subscribe();
}
A few points.
the stream must return the same type for merge to work. if combining streams of different types, use combine_latest instead.
the order of the observables in observable<>::from() is important, the start stream has ref_count, so it must be called last so that the following merge will have subscribed to the work before starting the generator.
The merge has two threads calling it. This requires that a thread-safe coordination be used. rxcpp is pay-for-use. by default the operators assume that all the calls are from the same thread. any operator that gets calls from multiple threads needs to be given a thread-safe coordination which the operator uses to impose thread-safe state management and output calls.
If desired the same coordinator instance could be used for both.

Unit Testing Reactive Extensions with a method using Wait

I am trying to unit test a method that uses the Wait() method on an IObservable however my test never completes - the Wait never finishes. My test contains the following:
var scheduler = new TestScheduler();
var input1 = scheduler.CreateColdObservable<List<string>>(
new Recorded<Notification<List<string>>>(100, Notification.CreateOnNext(new List<string> { "John", "Harry" })),
new Recorded<Notification<List<string>>>(200, Notification.CreateOnCompleted<List<string>>())
);
I am using Moq to setup the response on my method by returning input1. For example
myObj.Setup(f => f.GetStrings()).Returns(input1);
It doesn't actually matter about the details of myObj. I start the scheduler and call my method which contains a Wait(e.g somewhere in my method I call
var results = myObj.GetStrings().Wait();
But this never returns. I suspect I am using the scheduler wrong but I am not sure.
Regards
Alan
Summary
The problem is that you are creating a cold observable and advancing the scheduler before you have subscribed to it.
Detail
If you call the blocking Wait() operation on a single threaded test, you are dead in the water at that point. This is because the TestScheduler's internal clock only advances when you call Start() or one of the AdvanceXXX() methods and, since you have a cold observable, the event times you specify are relative the point of subscription. There are also some nuances to calling Start() which I will explain below.
So, as Wait will block, you might try to call it on another thread, but it's still tricky. Consider the following code, which is similar to yours:
void Main()
{
var scheduler = new TestScheduler();
var source = scheduler.CreateColdObservable(
new Recorded<Notification<int>>(100, Notification.CreateOnNext(1)),
new Recorded<Notification<int>>(200, Notification.CreateOnCompleted<int>()));
// (A)
int result = 0;
var resultTask = Task.Run(() => { result = source.Wait(); });
// (B)
resultTask.Wait();
Console.WriteLine(result);
}
This code tries to wait on a background thread. If we insert a call to scheduler.Start() at point (A), then source.Wait() will block forever.
This is because Start() will ONLY advance the internal clock of the TestScheduler until all currently scheduled events are executed. With a cold observable, events are scheduled relative to the virtual time of subscription. Since there are no subscribers at point (A), you will find that TestScheduler.Now.Ticks will report 0 even after the call to Start().
Hmmm. Things get even worse if we move the call to scheduler.Start() to point B. Now we have a race condition! It's a race condition that will almost always result in the test hanging at the call to resultTask.Wait(). This is because the chances are that the resultTask will not have had time to execute it's action and subscribe to source before the scheduler.Start() call executes - and so time once again will not advance.
A deterministic execution is therefore very hard to achieve - there is no nice way to announce that the Wait() call has been issued before advancing time, since the Wait() call itself will block. Inserting a long enough delay before calling Start() will work, but kind of defeats the object of using the TestScheduler:
// (B)
Task.Delay(2000).Wait();
scheduler.AdvanceBy(200);
What this question really demonstrates to me (IMHO) is that calling Wait() and blocking a thread is almost always a bad idea. Look for using methods like LastAsync() instead, and/or using continuations to get hold of results to asynchronous methods.
I can't recommend the approach due to the complexity, but here is a deterministic solution that makes use of an extension method to signal when a subscription has been made.
void Main()
{
var scheduler = new TestScheduler();
var source = scheduler.CreateColdObservable(
new Recorded<Notification<int>>(100, Notification.CreateOnNext(1)),
new Recorded<Notification<int>>(200, Notification.CreateOnCompleted<int>()));
// (A)
var waitHandle = new AutoResetEvent(false);
int result = 0;
var resultTask = Task.Run(() =>
{
result = source.AnnounceSubscription(waitHandle).Wait();
});
// (B)
waitHandle.WaitOne();
scheduler.Start();
resultTask.Wait();
Console.WriteLine(result);
}
public static class ObservableExtensions
{
public static IObservable<T> AnnounceSubscription<T>(
this IObservable<T> source, AutoResetEvent are)
{
return Observable.Create<T>(o =>
{
var sub = source.Subscribe(o);
are.Set();
return sub;
});
}
}
Recommended approach for testing Rx
A more idiomatic use of the TestScheduler is to create an observer to collect results, and then assert they meet expectations. Something like:
void Main()
{
var scheduler = new TestScheduler();
var source = scheduler.CreateColdObservable(
new Recorded<Notification<int>>(100, Notification.CreateOnNext(1)),
new Recorded<Notification<int>>(200, Notification.CreateOnCompleted<int>()));
var results = scheduler.CreateObserver<int>();
// here you would append to source the Rx calls that do something interesting
source.Subscribe(results);
scheduler.Start();
results.Messages.AssertEqual(
new Recorded<Notification<int>>(100, Notification.CreateOnNext(1)),
new Recorded<Notification<int>>(200, Notification.CreateOnCompleted<int>()));
}
Finally, if you derive a unit test class from ReactiveTest you can take advantage of OnNext, OnCompleted and OnError helper methods to create Recorded<Notification<T>> instances in a more readable fashion.