vaskir
06/16/2017, 7:03 PMclass ParallelBuilder<T> {
private val coroutines = ArrayList<Deferred<T>>()
fun prun(context: CoroutineContext = CommonPool,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T) {
coroutines.add(async(context, start, block))
}
suspend fun resume() = coroutines.map { it.await() }
}
inline suspend fun <R> parallel(crossinline builder: ParallelBuilder<R>.() -> Unit): List<R> {
val scope = ParallelBuilder<R>()
scope.builder()
return scope.resume()
}
fun main(args: Array<String>) = runBlocking {
val res = parallel<Int> {
prun {
println("1")
delay(1000)
println("1 done")
1
}
prun {
println("2")
delay(1000)
println("2 done")
2
}
prun {
println("3")
delay(1000)
println("3 done")
3
}
}
}
output
1
2
3
2 done
3 done
1 done
Result: [1, 2, 3]
I suspect there are a number of such functions already written 🙂 However, I didn't find one in the standard lib.oleksandr.samsonov
06/16/2017, 11:15 PMOmar Miatello
06/17/2017, 1:32 PMfun longJob(jobName: String) = launch(CommonPool) {
val easyWS = client.easyWebSocket("<ws://echo.websocket.org>")
println("[$jobName] Open: ${easyWS.response}")
launch(context) {
for (i in 1..3) {
delay(1000) // every 1s
val msg = "Hi, I am $jobName @ $i!"
println("[$jobName] --> $msg")
easyWS.webSocket.send(msg)
}
easyWS.webSocket.close(1000, "Bye! $jobName")
}
for (msg in easyWS.textChannel) {
println("[$jobName] <-- $msg")
}
println("[$jobName] Finish!")
}
Omar Miatello
06/17/2017, 1:37 PMsuspendCoroutine
to obtain webSocket
, and send all received message in a Channel<String>
(so I can loop all received message)Omar Miatello
06/17/2017, 1:43 PMlaunch(CommonPool)
, so I can run multiple jobs at the same time. Is it right?elizarov
06/17/2017, 2:59 PMOmar Miatello
06/17/2017, 3:00 PMOmar Miatello
06/17/2017, 3:00 PMelizarov
06/17/2017, 3:01 PMeasyWebSocket
implementation (a link to github repo or gist would be the best way to share)Omar Miatello
06/17/2017, 3:01 PMOmar Miatello
06/17/2017, 3:01 PMOmar Miatello
06/17/2017, 3:01 PMvaskir
06/17/2017, 3:02 PMlaunch
could use context
instead of CommonPool
Omar Miatello
06/17/2017, 3:11 PMelizarov
06/17/2017, 3:15 PMoverride fun onMessage(webSocket: WebSocket, text: String) {
launch(CommonPool) { easyWs!!.textChannel.send(text) }
}
It can reorder messages. I would replace launch
with runBlocking
here.elizarov
06/17/2017, 3:17 PMOkHttp
library has no other way of explicit back-pressure signalling, then you should not be shy to block its thread to signal back-pressure.Omar Miatello
06/17/2017, 3:23 PMsuspendCoroutine
+ runBlocking
+ Channel
) is a good practice when you try to wrap a complex callback?Omar Miatello
06/17/2017, 3:23 PMelizarov
06/17/2017, 8:23 PMvaskir
06/18/2017, 6:28 PMsuspend fun f() = 1
suspend fun h(f: suspend () -> Int) = ...
h(::f) // compilation error
vaskir
06/18/2017, 6:29 PMh { f() }
elizarov
06/18/2017, 7:13 PMvaskir
06/19/2017, 5:34 AMgroostav
06/19/2017, 8:35 AMelizarov
06/19/2017, 8:37 AMkenkyee
06/19/2017, 9:40 PMrestioson
06/20/2017, 10:54 AMrestioson
06/20/2017, 10:54 AMelizarov
06/20/2017, 11:25 AMrestioson
06/20/2017, 11:25 AM