elizarov
02/05/2017, 1:11 PMjdiaz
02/05/2017, 1:13 PMaleix
02/05/2017, 1:17 PMelizarov
02/05/2017, 1:27 PMWatchService
API is quite complex for a small example. Anyone has any idea of a simple blocking API that could be used as an example for blocking to non-blocking conversion for coroutines manual?aleix
02/05/2017, 1:34 PMelizarov
02/05/2017, 1:35 PMkenkyee
02/05/2017, 4:56 PMelizarov
02/05/2017, 7:45 PMsomeBlockingMethod()
and you, for example, want to invoke it from a coroutine that is confined to your UI thread (`Swing`/`JavaFx`/Android/whatever) without blocking your UI thread, then you just decide what thread (or pool) you want to execute your blocking call on (say in CommonPool
) and just use `run`:
run(CommonPool) { someBlockingMethod() }
elizarov
02/05/2017, 7:47 PMCommonPool
is blocked, your UI-confined coroutine is just suspended and you can do anything else in your UI thread.kenkyee
02/05/2017, 8:51 PMsuresh
02/05/2017, 9:00 PMmakeRequest
is a suspend
function, it blocks that common pool thread until it get a response.
val jobs = (1..1000).map { n ->
defer(CommonPool) {
try {
makeRequest(n)
}catch (e : Exception) {
Pair(n,e.message)
}
}
}
runBlocking {
jobs.forEach {
val r = it.await()
println("Got response for ${r.first} - ${r.second}")
}
}
suspend fun makeRequest(i : Int): Pair<Int, Int> {
println("Creating request $i")
val con = URL("<https://slack.com/>").openConnection() as HttpsURLConnection
con.connectTimeout = 1000
con.readTimeout = 1000
con.instanceFollowRedirects = true
con.requestMethod = "GET"
// sleep(1000)
return Pair(i, con.responseCode)
}
aleix
02/05/2017, 9:41 PMelizarov
02/06/2017, 6:46 AMelizarov
02/06/2017, 6:48 AMelizarov
02/06/2017, 6:49 AMelizarov
02/06/2017, 6:55 AMmarkRequest
with suspend
modifier. It will not magically become suspending if it still uses blocking APIs. It is still a blocking function. You should remove suspend
modifier from it to make it clear.elizarov
02/06/2017, 6:56 AMmakeRequest
in a CommonPool
, then you main thread does not block. The advantage is that it.await()
only suspends your main thread, and it is free process any other coroutines you might be running in your main thread.elizarov
02/06/2017, 7:04 AMit.await()
change your runBlocking
block to:
runBlocking {
launch(context) { // launch another coroutine in the context of this thread
while (true) {
println(”I’m not blocked!”)
delay(100)
}
}
jobs.forEach {
val r = it.await()
println("Got response for ${r.first} - ${r.second}")
}
}
sreich
02/06/2017, 9:56 AMadambl4
02/06/2017, 2:48 PM'kotlinx.coroutines.experimental.NonCancellable' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compilerDoes this mean that now I tightly coupled with version which kotlinx.coroutines uses?
hackerham
02/06/2017, 2:50 PMhackerham
02/06/2017, 2:50 PMhackerham
02/06/2017, 2:51 PMwalmyrcarvalho
02/07/2017, 12:29 PMcedric
02/07/2017, 3:02 PMvoddan
02/07/2017, 4:35 PMimport kotlinx.coroutines.experimental.*
is not resolved at http://try.kotlinlang.org/hackerham
02/07/2017, 4:37 PMimport kotlin.coroutines.experimental.*
suspend fun f() = suspendCoroutine<Unit> {
cont ->
println("YEAH")
cont.resume(Unit);
}
hackerham
02/07/2017, 4:37 PMhackerham
02/07/2017, 4:38 PMgroostav
02/07/2017, 6:53 PMclass someController(fileSystem: FancyAsyncFileSystem) {
override fun initialize() = suspending {
//things that call other suspend funs and async methods
}
@FXML fun handleWhateverAction(userAction: Event) = suspending {
val fileContent = await(fileSystem.loadFileAsync(Paths.get(textField.text)))
//things that call other suspend...
filePreviewArea.text = fileContent
}
}
and its test
class WhateverControllerTests {
@Test fun `when clicking on the whatever whatever should whatever the whatevers`(){
//setup
val fs = FakeFancyFileSystem().apply { setContent("a/b/c", "testing!") }
val controller = WhateverController(fs).apply {
textField.text = "a/b/c"
}
//act
controller.handleWhateverAction(NonDescriptEvent)
//problem: async computation started and because of the enforced `void`-ness of the java handlers, any reference to a Future object or something I can synchronize with is gone
//assert
assertThat(controller.filePreviewTextArea.text).isEqualTo("testing!")
}
}