What is the difference of 'async' before or after 'for' in X10? - x10-language

I'm currently learning for an exam. In an multiple choice question of an old exam are two different versions of a for loop marked as valid:
finish async for (i in array) async {
...
}
and
finish for (i in array) async {
...
}
What is the difference of those two versions?

async Statement
Spawns a new activity executing the Statement.
In your second version is one activity spawned per loop execution. If n is the size of your array you will spawn n activities.
In your first version you also spawn an extra activity for the loop itself: You spawn n + 1 activities.
You can write it also as: (which may be more clear for you)
finish async {
for (i in array) {
async {
...
}
}
}
Actually i don't have a source other than the language specification, but you can test the behaviour as it computes as expected. If you remove the first async no activity for the loop is created and "hello from starter" is printed after "hello from loop". With the extra async "hello from starter" will be printed first:
public static def main(Rail[String]) {
finish {
async { //to be removed
for (i in [1,2,3]) {
async {
Console.OUT.println("Hello from executing activity " + i + "!");
}
}
System.sleep(3000l); //wait 3s
Console.OUT.println("Hello from loop!");
}
Console.OUT.println("Hello from Starter!");
}
}

Related

How this piece of code can be improved and rewritten to kotlin coroutines

I'm trying to achieve functionality: I have a rest endpoint that calls code that execution can take a lot of time. My idea to improve experience for now is to wrap that piece of code as a new thread, wait for completion or for some max time to elapse and return an appropriate message. Wrapped code should be completed even through endpoint already send message back. Current implementation looks like this:
private const val N = 1000
private const val MAX_WAIT_TIME = 5000
#RestController
#RequestMapping("/long")
class SomeController(
val service: SomeService,
) {
private val executor = Executors.newFixedThreadPool(N)
#PostMapping
fun longEndpoint(#RequestParam("someParam") someParam: Long): ResponseEntity<String> {
val submit = executor.submit {
service.longExecution(someParam)
}
val start = System.currentTimeMillis()
while (System.currentTimeMillis() - start < MAX_WAIT_TIME) {
if (submit.isDone)
return ResponseEntity.ok("Done")
}
return ResponseEntity.ok("Check later")
}
}
First question is - waiting on while for time seems wrong, we don't release thread, can it be improved?
More important question - how to rewrite it to Kotlin coroutines?
My attempt, simple without returning as soon as task is done, looked like this:
#PostMapping
fun longEndpoint(#RequestParam("someParam") someParam: Long): ResponseEntity<String> = runBlocking {
val result = async {
withContext(Dispatchers.Default) {
service.longExecution(someParam)
}
}
delay(MAX_WAIT_TIME)
return#runBlocking ResponseEntity.ok(if(result.isCompleted) "Done" else "Check later")
}
But even through correct string is returned, answer is not send until longExecution is done. How to fix that, what am I missing? Maybe coroutines are bad application here?
There are several problems with your current coroutines attempt:
you are launching your async computation within runBlocking's scope, so the overall endpoint method will wait for child coroutines to finish, despite your attempt at return-ing before that.
delay() will always wait for MAX_WAIT_TIME even if the task is done quicker than that
(optional) you don't have to use runBlocking at all if your framework supports async controller methods (Spring WebFlux does support suspend functions in controllers)
For the first problem, remember that every time you launch a coroutine that should outlive your function, you have to use an external scope. coroutineScope or runBlocking are not appropriate in these cases because they will wait for your child coroutines to finish.
You can use the CoroutineScope() factory function to create a scope, but you need to think about the lifetime of your coroutine and when you want it cancelled. If the longExecution function has a bug and hangs forever, you don't want to leak the coroutines that call it and blow up your memory, so you should cancel those coroutines somehow. That's why you should store the scope as a variable in your class and cancel it when appropriate (when you want to give up on those operations).
For the second problem, using withTimeout is very common, but it doesn't fit your use case because you want the task to keep going even after you timeout waiting for it. One possible solution would be using select clauses to either wait until the job is done, or wait for some specified maximum time:
// TODO call scope.cancel() somewhere appropriate (when this component is not needed anymore)
val scope = CoroutineScope(Job())
#PostMapping
fun longEndpoint(#RequestParam("someParam") someParam: Long): ResponseEntity<String> {
val job = scope.launch {
longExecution()
}
val resultText = runBlocking {
select {
job.onJoin() { "Done" }
onTimeout(MAX_WAIT_TIME) { "Check later" }
}
}
return ResponseEntity.ok(resultText)
}
Note: I'm using launch instead of async because you don't seem to need the return value of longExecution here.
If you want to solve the problem #3 too, you can simply declare your handler suspend and remove runBlocking around the select:
// TODO call scope.cancel() somewhere appropriate (when this component is not needed anymore)
val scope = CoroutineScope(Job())
#PostMapping
suspend fun longEndpoint(#RequestParam("someParam") someParam: Long): ResponseEntity<String> {
val job = scope.launch {
longExecution()
}
val resultText = select {
job.onJoin() { "Done" }
onTimeout(MAX_WAIT_TIME) { "Check later" }
}
return ResponseEntity.ok(resultText)
}
Note that this requires spring-boot-starter-webflux instead of spring-boot-starter-web.
Your implementation always waits for MAX_WAIT_TIME. This might work:
#PostMapping
fun longEndpoint(#RequestParam("someParam") someParam: Long): ResponseEntity<String> = runBlocking {
try {
withTimeout(MAX_WAIT_TIME) {
async {
withContext(Dispatchers.Default) {
service.longExecution(someParam)
}
}
}
} catch (ex: CancellationException) {
return#runBlocking ResponseEntity.ok("Check later")
}
return#runBlocking ResponseEntity.ok("Done")
}
Although I'm not sure if there will be any unwanted side effects because it seems that this will cancel the coroutine when it reaches MAX_WAIT_TIME. Read more about it here:
Cancellation and timeouts

How to understand order of calling coroutines with scope?

I saw the coroutines example here.
To understand the example I made three different examples with each scope.
The printed number is the following #N.
It's just my opinion, so if there is a wrong thing, let me know.
#1: 3->1->2->4
runBlocking {
launch {
println("1-Task from runBlocking")
}
coroutineScope { // Creates a coroutine scope
launch {
println("2-Task from nested launch")
}
println("3-Task from coroutine scope")
}
println("4-Coroutine scope is over")
}
I understood the coroutineScope waits until the children will be completed. The outer runBlocking has two coroutines.
The first is launch of 1 and the second is in coroutineScope.
The coroutineScope will be handled first based on the call stack.
Thus the first printed number is 3 because it's within regular function.
And then the 1 can be printed before 2.
The 4 will be printed after coroutineScope block is finished.
#2: 1->3->2->4
runBlocking {
launch {
println("1-Task from runBlocking")
}
runBlocking { // Creates a coroutine scope
launch {
println("2-Task from nested launch")
}
println("3-Task from coroutine scope")
}
println("4-Coroutine scope is over")
}
runBlocking is not suspend function that's why the outer runBlocking doesn't have a coroutine. Thus the 1 will be printed first. After that, the inner runBlocking has one coroutine so wait until this block will be finished. Thus 3 and 2 will be printed. Last, 4 printed after inner runBlocking.
#3: 2->4->3->1, 4->3->2->1, 4->2->3->1
runBlocking {
launch {
println("1-Task from runBlocking")
}
GlobalScope.launch { // Creates a coroutine scope
launch {
println("2-Task from nested launch")
}
println("3-Task from coroutine scope")
}
println("4-Coroutine scope is over")
}
There are several different results so I guessed it depends on environments on runtime.
But I wonder if it's impossible to print 1 first or not.
Second, how to understand scope in other suspend or scope.

Can I call Deferred<>.await() many times?

I am newbie about coroutines and I have a simple question.
Can I call await() many times to get result value?
E.g.
class Test: CoroutineScope {
val my_value = async { "Hello World!" }
suspend fun f1() {
println(my_value.await())
}
suspend fun f2() {
println(my_value.await())
}
I suppose second call "await()" will immediately return computed value. It's right?
Tnx
You can call Deferred.await() as many times as you want/need. The result is simply returned or the exception is thrown again.

How to let withTimeoutOrNull return null but finish code in the block

I need my code to run a block and return value after 1 second in case timeout but let it finish the job.
I managed to implement something that works but IDE suggest replacing async with withContext(DefaultDispatcher) but it's not working the same.
So my question is how to make it work without IDE warnings. I am new to Kotlin Coroutines so I might be missing something here.
#Test
fun how_timeout_with_null_works() = runBlocking<Unit> {
val time = measureTimeMillis {
println("Start test")
val result = withTimeoutOrNull(1, TimeUnit.SECONDS) {
async { doSomeHardWork() }.await()
}
println("End test $result")
}
println("Time $time")
delay(3000)
}
private suspend fun doSomeHardWork(): String {
println("start hard work")
Thread.sleep(2000)
print("end hard work")
return "[hard work done]"
}
IDE gives a warning in this case because async(ctx) { ... }.await() is usually a mistake and withContext(ctx) { ... } usually better reflects the original intent of the author of the code.
In case of your code, your intent is different. Your intent is to await for 1 second, without constraining your doSomeHardWork code. However, the structure of your code does not reflect your intent. You've wrapped the whole block into withTimeout and put doSomeHardWork inside of it, while your intent was only to do a time-limited wait for it. So, if you rewrite your code in the way where the structure of your code matches your intent, it will work without any warnings:
val work = async { doSomeHardWork() } // start work
val result = withTimeoutOrNull(1, TimeUnit.SECONDS) { work.await() } // wait with timeout
If you happen to need this pattern of code more than once, then you can define yourself a handy extension:
suspend fun <T> Deferred<T>.awaitWithTimeout(time: Long, unit: TimeUnit): T? =
withTimeoutOrNull(time, unit) { await() }
And then write even nicer code that reflects your intent:
val result = async { doSomeHardWork() }.awaitWithTimeout(1, TimeUnit.SECONDS)
Be careful, though. These coroutines that you start with async will continue running after the wait had timed out. This can easily lead to resource leaks, unless you take steps to limit the number of those concurrently running background jobs.

Unity/C# : How to execute a function after another function has finished its execution?

I've been trying to build a "event system" for a project that I'm working on . Here is how I'm doing it : I populate a list with reference to a gameObject and the functions that I need to execute from that gameObject . Then , when the "event" is triggered (in this case , when the player steps into a trigger collider) I just loop over the list and Invoke the functions inside it.
The problem with this is that every single function inside the list gets executed at the same time. This works fine in some cases but if I want to create a more cinematic event I need to have the ability to execute a function after the previous one has finished it's execution .Sadly I have no idea how to do that.
I've been reading a lot of the documentation of both Unity and C# about coroutines and delegates but I can't seem to wrap my head around all those things and find a way to do implement them on code .So I need your help with that :How can I achieve this?
1) use Invoke
private void BeginRace()
{
Invoke("WaveFlag", 0.5f);
Invoke("Beeps", 1.5f);
Invoke("CrowdBeginsCheer", 2f);
Invoke("CarsStartMoving", 2.2f);
}
2) use coroutine
private void BeginRace()
{
StartCoroutine(RaceSequence());
}
private IEnumerator RaceSequence()
{
yield return new WaitForSeconds(.5f);
WaveFlag();
yield return new WaitForSeconds(1f);
Beeps();
yield return new WaitForSeconds(.5f);
CrowBeginsCheer();
yield return new WaitForSeconds(.2f);
CarsStartMoving();
}
You must master both coroutines and Invoke. Be sure to simply use Invoke when possible. Avoid coroutines when you are just learning Unity. (Advanced essay on coroutines.)
3) "I need to wait until the previous function has ended before executing the following one"
a) EACH OF THOSE FUNCTIONS must be an IEnumerator
private IEnumerator ExplodeCar()
{
..
}
private IEnumerator CrowdReaction()
{
..
}
private IEnumerator WinningCelebration()
{
..
}
b) To call them one after the other, waiting for each to finish
private void Sequence()
{
StartCoroutine(Seq())
}
private IEnumerator Seq()
{
yield return StartCoroutine(ExplodeCar());
yield return StartCoroutine(CrowdReaction());
yield return StartCoroutine(WinningCelebration());
}
Footnotes
If you want to wait until the next frame, use:
yield return null;
if you have a "stack" of things you want to do each frame, just do this
void Update()
{
if (newItem = yourStack.Pop())
newItem();
}
if you have a "stack" of things you want to do waiting for each to finish,
void Start()
{
StartCoroutine(YourStackLoop());
}
private IEnumerator stackLoop()
{
while(true)
{
if (newItem = yourStack.Pop())
yield return StartCoroutine(newItem());
else
yield return new;
}
}
Note that Update and a coroutine are fundamentally the same thing, read and study on this.
Note in the example, use your own usual Push/Pop (or FIFO, or whatever you wish). If unfamiliar, search many QA on here.

Resources