https://kotlinlang.org logo
#coroutines
Title
# coroutines
o

otakusenpai

10/15/2018, 12:45 PM
Hey guys, So I have a server class which contains a map of strings to bots, and theres this function in the server class called runBots() which run all the bots. This is what I have for a implementation:
Copy code
fun runBots() = runBlocking {
        try {
            bots.forEach {
                val one = launch { it.value.setConnection(); }
                one.join()
                delay(3000L)
                if(it.value.running) {
                    it.value.Connect()
                }
            }
        } catch(e: Throwable) {
            bots.forEach { if(!it.value.running) it.value.Connect() }
        }
    }
"bots" here is the map of strings to bots. Each bot has a Connect() function(a async function) which runs the all the bot's main loop. The problem is that the bot doesnt run, after the server class calls it's runBots function.
Copy code
Initialised
Connnected: true
Defined bot
Added bot
[main] Connecting....
[main] Sending nick...
Sending nick: NICK Kraken3635

[main] Sending user...
Sending user: USER Nani 0 * :Nani

[main] Connected!
[DefaultDispatcher-worker-1] I'm now in Connect!
[DefaultDispatcher-worker-1] Entering loop...
e

enleur

10/15/2018, 1:11 PM
async you mean you do launch inside Connect?
o

otakusenpai

10/15/2018, 1:13 PM
yes each Connect is a loop which runs the internals of each bot, and the declaration of Connect is as such:
Copy code
fun Connect() = GlobalScope.async { ... }
e

enleur

10/15/2018, 1:17 PM
i see. you should use structured concurrency:
Copy code
fun CoroutineScope.Connect() = launch { ... }
in this case your
runBlocking
call does not exit until child launches complete whatever they do
in your case, you do launch in different scope, so runBlocking does not have any reason to be running
o

otakusenpai

10/15/2018, 1:18 PM
ok, where can i read more about this?
e
o

otakusenpai

10/15/2018, 1:19 PM
thnx a lot
o

otakusenpai

10/15/2018, 1:20 PM
thnx
g

gildor

10/15/2018, 1:34 PM
Yes, Connect with coroutine scope is preferred way to implement this, but you can fix existing code if you
join
result of connect, but to do this in parallel you can replace forEach with map and than call joinAll on list of jobs
e

enleur

10/15/2018, 1:35 PM
and replace
async
with
launch
then
g

gildor

10/15/2018, 1:35 PM
Only if you need result of operation
Otherwise launch is also fine
e

enleur

10/15/2018, 1:35 PM
Copy code
val one = launch { it.value.setConnection(); }
                one.join()
what is the reason behind this?
g

gildor

10/15/2018, 1:36 PM
Yes, Sergey was faster :) Also want to ask about this code, it doesn't make sense
o

otakusenpai

10/15/2018, 1:38 PM
Also should i make the server class the CoroutineScope main class or should i make the bot class the coroutinescope main class?
g

gildor

10/15/2018, 1:39 PM
Actually I really curious why Connect calls launch inside, usually you don't need such code
o

otakusenpai

10/15/2018, 1:40 PM
well my purpose was to create a bot's main loop on its own coroutine
g

gildor

10/15/2018, 1:40 PM
Why?
Preferred and recommended style to use suspend functions
o

otakusenpai

10/15/2018, 1:40 PM
well, to make it run faster maybe, i could initialise many bots and run them parallely then
g

gildor

10/15/2018, 1:42 PM
Much better to parallel operation only when you need it
So I would remove launch from Connect and instead move it to your runBoth function
So you explicitly parallel jobs
o

otakusenpai

10/15/2018, 1:43 PM
ok
g

gildor

10/15/2018, 1:43 PM
Also you avoid problems with global scope
And you don't need any joins in this case
o

otakusenpai

10/15/2018, 1:46 PM
ok thanks
g

gildor

10/15/2018, 1:47 PM
It uses the same approach as you original code, but has remark about this and then demonstrates recommended approach:
This programming style with async functions is provided here only for illustration, because it is a popular style in other programming languages. Using this style with Kotlin coroutines is strongly discouraged for the reasons that are explained below.
o

otakusenpai

10/15/2018, 1:48 PM
yeah its the same page given above
g

gildor

10/15/2018, 1:48 PM
Yeah, right
3 Views