Daniel
07/10/2020, 6:48 PMandylamax
07/11/2020, 4:41 AMcancel
on a CoroutineScope
preven't it from launching coroutines in the near future?Tim Malseed
07/11/2020, 5:32 AMsuspend fun getAudio(songId: Long): AudioStream? {
return withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
songRepository.getSongs(SongQuery.SongIds(listOf(songId))).firstOrNull()?.firstOrNull()?.let { song ->
val uri = Uri.parse(song.path)
if (song.path.startsWith("content://")) {
if (DocumentsContract.isDocumentUri(context, uri)) {
val documentFile = DocumentFile.fromSingleUri(context, uri)
documentFile?.let {
context.contentResolver.openInputStream(documentFile.uri)?.let { inputStream ->
AudioStream(inputStream, documentFile.length(), documentFile.type ?: "audio/*")
}
}
} else {
context.contentResolver.openInputStream(uri)?.let { inputStream ->
AudioStream(inputStream, song.size, song.mimeType)
}
}
} else {
AudioStream(File(uri.toString()).inputStream(), song.size, song.mimeType)
}
}
}
}
AS complains that openInputStream()
is an ‘inappropriate blocking call’
Is this a false positive by AS, or am I doing something wrong here?louiscad
07/11/2020, 6:38 PMFlow
? If so, please react with ➕. I personally did (and that made a minor bug reach production), so I submitted a feature request: https://youtrack.jetbrains.com/issue/KT-40228iex
07/12/2020, 4:59 PMprivate suspend fun myStruct(): MyStruct = MyStruct(1) {
foo()
}
suspend fun foo() {}
private data class MyStruct(
val a: Int,
val callback: (() -> Unit)?
)
iex
07/12/2020, 5:24 PMBroadcastChannel.send
in a suspended function? With e.g. RxJava pushing events to a subject doesn't require anything special.immathan
07/13/2020, 2:05 PMbackoff
strategy using the flow.
fun main() {
runBlocking {
(0..8).asFlow()
.flatMapConcat { input ->
// To simulate a flow which fetches data based on a time-window which is exponentially increased if there's no data
// available with in that time frame.
flow {
println("Input: $input")
if (input < 5) {
emit(emptyList<String>())
} else { // After emitting this once the flow should complete
emit(listOf("Available"))
}
}.retryWhenThrow(DummyException(), predicate = {
it.isNotEmpty()
})
}.collect {
//println(it)
}
}
}
class DummyException : Exception("Collected size is empty")
private inline fun <T> Flow<T>.retryWhenThrow(
throwable: Throwable,
crossinline predicate: suspend (T) -> Boolean
): Flow<T> {
return flow {
collect { value ->
if (!predicate(value)) {
throw throwable // informing the upstream to keep emitting since the condition is met
}
println("Value: $value")
emit(value)
}
}.catch { e ->
if (e::class != throwable::class) throw e
}
}
If you run this example in kotlin play ground you will notice that the flow keep emitting the value even after my condition is met(Where the list is not empty anymore). After much digging I found that I need something like takeUntil from rxJava. I need some help how I should proceed this.julian
07/14/2020, 6:36 PMFlow<Flow<T>>
to Flow<T>
?julian
07/14/2020, 8:01 PMval f: Flow<Int> = flow<Int> { emit(1) }.transform<Int, Int> { emit(it) }
When I compile, I get
Error:(6, 32) Kotlin: Unresolved reference: transform
Error:(10, 47) Kotlin: Unresolved reference: transform
Error:(10, 69) Kotlin: Unresolved reference: emit
Error:(10, 74) Kotlin: Unresolved reference: it
So I set up a new project with the same dependency on kotlinx-coroutines-core:1.3.7
. That works fine.
Also, oddly, all my other flow-related code that doesn't use transform
is fine.
Has anyone else encountered this before?matthew graf
07/14/2020, 10:39 PMrunBlockingTest
vs runBlocking
? runBlockingTest
seems to have some nice features, but this line in the documentation makes it sound like there is some risk of deprecation
This API is experimental and it is may change before migrating out of experimental (while it is marked as @ExperimentalCoroutinesApi). Changes during experimental may have deprecation applied when possible, but it is not advised to use the API in stable code before it leaves experimental due to possible breaking changes.
Luis Munoz
07/15/2020, 1:30 AM@Test
fun `experimental`() {
runBlocking {
val scope = CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>)
val songs = listOf("a", "b", "c", "d", "e")
songs.asFlow().flatMapMerge {
requestFlow("${Thread.currentThread().name} $it check")
}
.collect {
println("$it")
}
}
}
fun requestFlow(i: String): Flow<String> = flow {
emit("$i: First")
Thread.sleep(1000)
emit("$i: Second")
}
handstandsam
07/15/2020, 2:28 PMKotlin Actors - No Drama Concurrency
https://speakerdeck.com/handstandsam/kotlin-actors-no-drama-concurrencyAstronaut4449
07/15/2020, 3:30 PMasync
-coroutine-builder of the kotlinx.coroutines library can throw exceptions since the coroutine builder itself does not throw an exception but the .await()
does?
/**
* @throws[IllegalStateException] ... <- would this be correct?
*/
fun CoroutineScope.doStuffAsync() = async { ... }
Tamas
07/15/2020, 5:38 PMproduce
I have imported it from import kotlinx.coroutines.channels.produce
but the ide still displays it red, and says create function
on alt-enter. my dependencies are
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.3.7'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.3.7'
Tim Malseed
07/16/2020, 3:37 AMcoroutineScope.launch {
val songs = mutableListOf<Song>()
mediaProvider.findSongs().collect { (song, progress) ->
songs.add(song)
listeners.forEach { listener -> listener.onProgress(progress, song) }
}
listeners.forEach { listener -> listener.onComplete() }
}
The scope is instantiated via CoroutineScope(Dispatchers.Main)
Despite listener.onProgress
being called on the main thread - and successful log messages when it is called, the UI updates I’m making in response don’t seem to have any effect.
Are the listener.onProgress(progress, song)
calls somehow being gathered up and then all executed at the end?
Ooh I think I might be blocking the main thread somewhereJustin
07/16/2020, 4:41 AMTim Malseed
07/16/2020, 6:29 AMoverride fun loadData() {
launch {
songRepository.getSongs(SongQuery.Album(name = album.name, albumArtistName = album.albumArtist))
.collect { songs ->
this@AlbumDetailPresenter.songs = songs
view?.setData(songs)
}
}
}
But this doesn’t:
override fun loadData() {
launch {
songRepository.getSongs(SongQuery.Album(name = album.name, albumArtistName = album.albumArtist))
.collect { songs ->
this@AlbumDetailPresenter.songs = songs
}
view?.setData(songs)
}
}
TwoClocks
07/16/2020, 7:53 PMelizarov
07/16/2020, 9:59 PMkotlinx.coroutines
version 1.3.8
is released. It is an incremental update with several bug-fixes, a few improvements, and a couple minor features (experimental). Change log is here: https://github.com/Kotlin/kotlinx.coroutines/releases/tag/1.3.8enighma
07/16/2020, 10:20 PMGabriel Feo
07/17/2020, 12:40 AMprivate val state = MutableStateFlow(initialState)
fun getState(events: Flow<Event>): Flow<State> =
merge(
state,
events.transformLatest {
emit(state.value.copy(...))
...
emit(state.value.copy(...))
}
).onEach { state.value = it }
Think I'm missing something here, the second emit calling state.value
gets the same value as the first onetjohnn
07/18/2020, 4:37 AMdata class Count(var value: Int = 0)
private val count = MutableStateFlow(Count())
val newCount = count.value
newCount.value++ // no emission though value is updated
count.value = newCount // this does not emit either
gumil
07/18/2020, 11:04 AMyield
in production code? I rarely see it being used and only seen it used in tests. I wanted to know people's opinion if they ever used this function.Slackbot
07/19/2020, 5:40 PMallan.conda
07/20/2020, 10:51 AMMaciek
07/20/2020, 11:50 AMgsala
07/20/2020, 2:05 PMIn fact, there are valid use-cases where you have an entity with its own life-time, like a HTTP connection, and a client code in another module of your application making a request in its own scope. You should be able to easily combine them so that request is restricted to both life-times. Currently, this is cumbersome to implement.What's the right approach to combine two different scopes/lifecycles when launching a coroutine? In my case I have a BLE connection which creates a scope bound to the lifecycle of the connection, and I'd like a client to be able to launch a task to send a message, but also within the scope in which this client lives. This is for an Android project, so client would normally be a Fragment or ViewModel
Vincent Williams
07/20/2020, 11:20 PMdorf
07/20/2020, 11:32 PMRechee Jozil
07/21/2020, 3:41 AMRechee Jozil
07/21/2020, 3:41 AMoctylFractal
07/21/2020, 3:42 AMRechee Jozil
07/21/2020, 3:43 AMgildor
07/21/2020, 3:48 AM