What is lost after converting Monix `Task` to Cats `IO`? - multithreading

This simplified case is where my question happen at...
object Main extends IOApp{
def run(args:Seq[String]): IO[ExitCode]={
Task{...}
.to[IO]
.as(ExitCode.Success)
}
}
Another option is Await.result(task), however which sounds not quite line up with IOApp's practice.
what i know
According to this great post Monix vs Cats Effect
I see differences between Task IO are:
Task API is richer than IO
Task is smarter and automatic about thread scheduling fairness
Task get more cancelable options
and more ...
question and my opinion
What I lost after I convert Monix Task into Cats IO?
It seems to work fine, with Task.gather and timeout-- all those Task specific things.
So What I lost in conversion ?
If no, then no reason to have more than one data type created.
So given the differences is that means that I lost the scheduling fairness after conversing Task to IO ?
Well I should have verified it by myself but I don't known how to test it the fairness.

Related

How can I monitor stalled tasks?

I am running a Rust app with Tokio in prod. In the last version i had a bug, and some requests caused my code to go into an infinite loop.
What happened is while the task that got into the loop was stuck, all the other task continue to work well and processing requests, that happened until the number of stalling tasks was high enough to cause my program to be unresponsive.
My problem is took a lot of time to our monitoring systems to identify that something go wrong. For example, the task that answer to Kubernetes' health check works well and I wasn't able to identify that I have stalled tasks in my system.
So my question is if there's a way to identify and alert in such cases?
If i could find way to define timeout on task, and if it's not return to the scheduler after X seconds/millis to mark the task as stalled, that will be a good enough solution for me.
Using tracing might be an option here: following issue 2655 every tokio task should have a span. Alongside tracing-futures this means you should get a tracing event every time a task is entered or suspended (see this example), by adding the relevant data (e.g. task id / request id / ...) you should then be able to feed this information to an analysis tool in order to know:
that a task is blocked (was resumed then never suspended again)
if you add your own spans, that a "userland" span was never exited / closed, which might mean it's stuck in a non-blocking loop (which is also an issue though somewhat less so)
I think that's about the extent of it: as noted by issue 2510, tokio doesn't yet use the tracing information it generates and so provide no "built-in" introspection facilities.

Classful Thread Pool

I need to design a thread pool system, in Python in this case, but I'm more interested in the general methodology.
It has to be something along the lines of https://www.metachris.com/2016/04/python-threadpool/, where threads wait idling until some jobs are pushed into the pool. How that works, using condition variables, is clear to me.
I have one additional requirement though: the jobs I'm pushing into the pool cannot run all in parallel. Each of them has a class (i don't mean the object class here, just a simple integer that somehow classifies the job) and only one job per class can be running at the same time. If a job is pushed having the same class of a job that is currently running, it has to wait in the queue until the latter is done.
I have already modified the mentioned class to do this, but what I achieved is pretty messy and I'm not sure it's reliable, so I would ask what modifications would be suggested or whether I should use a totally different approach. Again: I don't need the code, but rather a description.
Thanks.

What is the Cocoa-way of observing progress of a background task?

Imagine the following situation: you have a background task (the term "task" here means a random computational unit, not an NSTask!), that is implemented using any of the modern technology such as Grand Central Dispatch or Operation Queues. Some controller object on main thread wants to monitor the progress of this background task and report it to a user.
Task progress can have following characteristics:
Be indeterminate or determinate
Because controller object must know when to switch NSProgressIndicator to the appropriate style. We can use a convention that progress is treated as indeterminate until the actual progress value raises from zero.
Progress value itself
A simple float value
Localized description of a current phase
NSString, because communication with user is good
What design suits these requirements at best while being the most Cocoa-ish?
There can be variants.
Delegation
Before firing up the task set your controller object as delegate.
#protocol MyBackgroundTaskDelegate
#required
- (void) progress: (float) value; // 0.0…1.0
#optional
- (void) workingOn: (NSString*) msg; // #"Doing this, doing that…"
#end
Actually, i successfully used this template many times, but it feels a little too verbose.
Block callback
Very similar to delegation, but keeps code in one place.
// Starting our background task...
[MyTask startComputationWithProgressHandler: ^(float progress, NSString* msg)
{
// Switching to the main thread because all UI stuff should go there...
dispatch_async(dispatch_get_main_queue(), ^()
{
self.progressIndicator.progress = progress;
self.informationalMessage = msg;
});
}];
KVO or polling of a progress properties
In this case background task object must have two properties similar to these:
#property(readonly, atomic) float progress;
#property(readonly, atomic) NSString* message;
And a client (our controller object) should set itself as an observer of these properties. The major flaw i see in this solution is that KVO-notifications always arrive on the same thread that caused the change. While you can force your observer (callback) method to run on a particular GCD queue it may not be always appropriate.
NSNotificationCenter
Background task sends notifications and client listens to them.
Is there any other patterns applicable to this situation? What solution can be treated as a most modern and Cocoa-ish?
When it comes to What is the Cocoa-way of observing progress of a background task? I would say delegation and NSNotificationCenter because blocks and KVO were introduced later, and hence didn't originally exist in the first Cocoa code writting years. In fact optional protocol methods were not present in previous objc versions too, everything was required by default.
From that you can actually see that blocks are a simpler way of implementing adhoc delegates, where the receiver of the block declares what parameters are passed to the block, and you are free to do whatever you want with them in your block. And KVO seems to be a less boilerplate way of implementing NSNotification with a more standardized approach to properties, useful for joining the UI created in what previously was called Interface Bilder, and simplifying the "what the hell do I have to do to know when this value changes" which requires a lot of documentation with NSNotification and long constants.
But I still think that there are places for each of these techniques: blocks are nice for mini-adhoc protocols, but would be a serious bother if you need a medium or higher interface area or bidirectional interface, and KVO doesn't help with watching global variables or values outside of a class/object, or stuff you don't want to make part of your public interface.
So my definitive answer is:
1 to 1 simple communication: blocks
1 to 1 complex communication: delegates/protocols
1 to many simple communication: KVO (where possible)
1 to many complex communication: NSNotifications
As always, pick the best tool for each problem, and consider I'm guilty of implementing all of the above in none of the suggested ways!
For the type of task you describe, I feel that NSNotificationCenter is the best option for a generic pattern. The reason is that you can't know, generally, how many external observers there are. The notification system already supports an arbitrary number of observers for an event, whereas the other non-polling options (delegation and blocks) are more typically one-to-one unless you do extra work to support multiple registrations.
As you pointed out yourself, polling is a bad idea if you can avoid it.
In my experience delegation or block callback are the best design choices. Choosing one over the other is mostly dictated by which one is more convenient to code and support for the particular situation. Both are asynchronous. Block callbacks usually reduce the necessity for additional instance variables since blocks capture variables within their scope. Of course for both it's necessary to be aware on which thread the call back is executed or delegate method is called.
I'd go with KVO because you get it for free when using #properties basically.
BUT
I would not recommend using plain KVO. because that will always call - observerValueOfKeyPath... and once you observe multiple keypaths it gets annoying to maintain. you have this mega function with lots of if(keyPath==bla)......
I recommend MAKVONotificationCenter by MikeAsh for this. It also saves you from many a crash when you forget to remove an observer when you dont need it anymore

What are the benefits of coroutines?

I've been learning some lua for game development. I heard about coroutines in other languages but really came up on them in lua. I just don't really understand how useful they are, I heard a lot of talk how it can be a way to do multi-threaded things but aren't they run in order? So what benefit would there be from normal functions that also run in order? I'm just not getting how different they are from functions except that they can pause and let another run for a second. Seems like the use case scenarios wouldn't be that huge to me.
Anyone care to shed some light as to why someone would benefit from them?
Especially insight from a game programming perspective would be nice^^
OK, think in terms of game development.
Let's say you're doing a cutscene or perhaps a tutorial. Either way, what you have are an ordered sequence of commands sent to some number of entities. An entity moves to a location, talks to a guy, then walks elsewhere. And so forth. Some commands cannot start until others have finished.
Now look back at how your game works. Every frame, it must process AI, collision tests, animation, rendering, and sound, among possibly other things. You can only think every frame. So how do you put this kind of code in, where you have to wait for some action to complete before doing the next one?
If you built a system in C++, what you would have is something that ran before the AI. It would have a sequence of commands to process. Some of those commands would be instantaneous, like "tell entity X to go here" or "spawn entity Y here." Others would have to wait, such as "tell entity Z to go here and don't process anymore commands until it has gone here." The command processor would have to be called every frame, and it would have to understand complex conditions like "entity is at location" and so forth.
In Lua, it would look like this:
local entityX = game:GetEntity("entityX");
entityX:GoToLocation(locX);
local entityY = game:SpawnEntity("entityY", locY);
local entityZ = game:GetEntity("entityZ");
entityZ:GoToLocation(locZ);
do
coroutine.yield();
until (entityZ:isAtLocation(locZ));
return;
On the C++ size, you would resume this script once per frame until it is done. Once it returns, you know that the cutscene is over, so you can return control to the user.
Look at how simple that Lua logic is. It does exactly what it says it does. It's clear, obvious, and therefore very difficult to get wrong.
The power of coroutines is in being able to partially accomplish some task, wait for a condition to become true, then move on to the next task.
Coroutines in a game:
Easy to use, Easy to screw up when used in many places.
Just be careful and not use it in many places.
Don't make your Entire AI code dependent on Coroutines.
Coroutines are good for making a quick fix when a state is introduced which did not exist before.
This is exactly what java does. Sleep() and Wait()
Both functions are the best ways to make it impossible to debug your game.
If I were you I would completely avoid any code which has to use a Wait() function like a Coroutine does.
OpenGL API is something you should take note of. It never uses a wait() function but instead uses a clean state machine which knows exactly what state what object is at.
If you use coroutines you end with up so many stateless pieces of code that it most surely will be overwhelming to debug.
Coroutines are good when you are making an application like Text Editor ..bank application .. server ..database etc (not a game).
Bad when you are making a game where anything can happen at any point of time, you need to have states.
So, in my view coroutines are a bad way of programming and a excuse to write small stateless code.
But that's just me.
It's more like a religion. Some people believe in coroutines, some don't. The usecase, the implementation and the environment all together will result into a benefit or not.
Don't trust benchmarks which try to proof that coroutines on a multicore cpu are faster than a loop in a single thread: it would be a shame if it were slower!
If this runs later on some hardware where all cores are always under load, it will turn out to be slower - ups...
So there is no benefit per se.
Sometimes it's convenient to use. But if you end up with tons of coroutines yielding and states that went out of scope you'll curse coroutines. But at least it isn't the coroutines framework, it's still you.
We use them on a project I am working on. The main benefit for us is that sometimes with asynchronous code, there are points where it is important that certain parts are run in order because of some dependencies. If you use coroutines, you can force one process to wait for another process to complete. They aren't the only way to do this, but they can be a lot simpler than some other methods.
I'm just not getting how different they are from functions except that
they can pause and let another run for a second.
That's a pretty important property. I worked on a game engine which used them for timing. For example, we had an engine that ran at 10 ticks a second, and you could WaitTicks(x) to wait x number of ticks, and in the user layer, you could run WaitFrames(x) to wait x frames.
Even professional native concurrency libraries use the same kind of yielding behaviour.
Lots of good examples for game developers. I'll give another in the application extension space. Consider the scenario where the application has an engine that can run a users routines in Lua while doing the core functionality in C. If the user needs to wait for the engine to get to a specific state (e.g. waiting for data to be received), you either have to:
multi-thread the C program to run Lua in a separate thread and add in locking and synchronization methods,
abend the Lua routine and retry from the beginning with a state passed to the function to skip anything, least you rerun some code that should only be run once, or
yield the Lua routine and resume it once the state has been reached in C
The third option is the easiest for me to implement, avoiding the need to handle multi-threading on multiple platforms. It also allows the user's code to run unmodified, appearing as if the function they called took a long time.

Using TDD to drive out thread-safe code

What's a good way to leverage TDD to drive out thread-safe code? For example, say I have a factory method that utilizes lazy initialization to create only one instance of a class, and return it thereafter:
private TextLineEncoder textLineEncoder;
...
public ProtocolEncoder getEncoder() throws Exception {
if(textLineEncoder == null)
textLineEncoder = new TextLineEncoder();
return textLineEncoder;
}
Now, I want to write a test in good TDD fashion that forces me to make this code thread-safe. Specifically, when two threads call this method at the same time, I don't want to create two instances and discard one. This is easily done, but how can I write a test that makes me do it?
I'm asking this in Java, but the answer should be more broadly applicable.
You could inject a "provider" (a really simple factory) that is responsible for just this line:
textLineEncoder = new TextLineEncoder();
Then your test would inject a really slow implementation of the provider. That way the two threads in the test could more easily collide. You could go as far as have the first thread wait on a Semaphore that would be released by the second thread. Then success of the test would ensure that the waiting thread times out. By giving the first thread a head-start you can make sure that it's waiting before the second one releases.
It's hard, though possible - possibly harder than it's worth. Known solutions involve instrumenting the code under test. The discussion here, "Extreme Programming Challenge Fourteen" is worth sifting through.
In the book Clean Code there are some tips on how to test concurrent code. One tip that has helped me to find concurrency bugs, is running concurrently more tests than the CPU has cores.
In my project, running the tests takes about 2 seconds on my quad core machine. When I want to test the concurrent parts (there are some tests for that), I hold down in IntelliJ IDEA the hotkey for running all tests, until I see in the status bar that 20, 50 or 100 test runs are in execution. I follow in Windows Task Manager the CPU and memory usage, to find out when all the test runs have finished executing (memory usage goes up by 1-2 GB when they all are running and then slowly goes back down).
Then I close one by one all the test run output dialogs, and check that there were no failures. Sometimes there are failed tests or tests which are in deadlock, and then I investigate them until I find the bug and have fixed it. That has helped me to find a couple of nasty concurrency bugs. The most important thing, when facing an exception/deadlock that should not have happened, is always assuming that the code is broken, and investigating the reason ruthlessly and fixing it. There are no cosmic rays which cause programs to crash randomly - bugs in code cause programs to crash.
There are also frameworks such as http://www.alphaworks.ibm.com/tech/contest which use bytecode manipulation to force the code to do more thread switching, thus increasing the probability of making concurrency bugs visible.
When I test drove an implementation that needed to be thread safe recently I came up with the solution I provided as an answer for this question. Hope that helps even though there are no tests there. Hope link is OK raher than duplicating teh answer...
Chapter 12 of Java Concurrency in Practice is called "Testing Concurrent Programs". It documents testing for safety and liveness, but says this is a hard subject. I am not sure this problem is solvable by the tools of that chapter.
Just off the top of my head could you compare the instances returned to see if they are indeed the same instance or if they are different? That's probably where I would start with C#, I would imagine you can do the same in java

Resources