Jarroyoesp
09/24/2020, 3:42 PMkotlinVersion = "1.4.0"
ktorVersion = "1.4.0"
coroutineVersion = "1.3.9-native-mt-2"
serializerVersion = "1.0.0-RC"
internal actual val ApplicationDispatcher: CoroutineContext =
NsQueueDispatcher(dispatch_get_main_queue())
internal class NsQueueDispatcher(
private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatchQueue) {
block.run()
}
}
}
But when I try to create HttpClient this exception is thrown(kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.ChildHandleNode
):
private val client by lazy {
HttpClient() {
install(JsonFeature) {
serializer = KotlinxSerializer(nonStrictJson)
}
install(Logging) {
logger = Logger.DEFAULT
level = <http://LogLevel.INFO|LogLevel.INFO>
}
}
}
Has anyone had the same problem? Thanks in advance.Andrea Giuliano
09/24/2020, 5:09 PMwithTimeout
function and I’ve noticed that if the block inside is not a suspending function, withTimeout simply does nothing.
Is that the expected behaviour? I know from the spec it’s stated that the block is a suspending block. However I was expecting at least some error or warning if the block is not suspending. Anything I’m missing here?cueball
09/24/2020, 6:22 PMreactive.function.client
method awaitBody()
from a Generic class and am running into error:
Kotlin: Cannot use 'Response' as reified type parameter. Use a class instead.
---
class ReactiveWebClient<Request: Any, Response: Any> {
suspend fun post(uri: URI, request: Request, headers: (HttpHeaders) -> Unit): Response {
return <http://webClient.post|webClient.post>()
.uri(uri)
.body(BodyInserters.fromValue(request))
.headers(headers)
.retrieve()
.awaitBody() // error on this line
}
}
Signature of `awaitBody`:
public suspend inline fun <reified T : kotlin.Any> org.springframework.web.reactive.function.client.WebClient.ResponseSpec.awaitBody(): T { /* compiled code */ }
Can someone please help? I’m not so well versed with Kotlin’s type parameters.Nick
09/24/2020, 8:54 PMcallbackFlow
and flatMapMerge
because they are marked as @FlowPreview
and @ExperimentalCoroutinesApi
. Does anyone have any idea when we can expect these to become stable?ribesg
09/25/2020, 10:25 AMhttp.get
will freeze the coroutine it runs in and I’m trying to prevent it from propagating outside coroutineScope { }
but my entire codebase still gets frozen...
override suspend fun getUsers(): List<User> {
val http = http.freeze()
val url = "$BASE_URL$USERS_PATH".freeze()
val result =
coroutineScope {
http.get<List<User>>(url)
}
return result
}
How do you properly isolate such call? I’ve been trying random things for daysCasey Brooks
09/25/2020, 3:38 PMwithContext(ioDispatcher)
block (ioDispatcher
is injected and is a TestCoroutineDispatcher
in unit tests)Florian
09/26/2020, 7:55 AMreceive
suspends till an event is sent over the channel, but the return type is Unit
so I ignore the return value)Allan Wang
09/26/2020, 8:11 AMcollectWhile
function?Florian
09/26/2020, 8:22 AMviewModelScope
for database operations (Room)? Theoretically, it could be canceled prematurely if we leave the app before the operation is done (although I don't know if it's possible to leave the app that fast), right? Do you do anything specific to prevent this?Allan Wang
09/26/2020, 9:57 AMwithContext(CoroutineExceptionHandler { … }) { … }
, or are exception handlers only usable in launch
and async
?spierce7
09/26/2020, 8:41 PMFlow
, what’s the best way to call something when the context it’s running in is cancelled? i.e. when the flow is cancelled, I need to call `process.destroy()`:
actual fun run(command: String): Flow<String> = flow {
val split = command.split(' ')
val process = ProcessBuilder(split).apply {
redirectErrorStream(true)
}.start()
process.inputStream.source().use { processSource ->
processSource.buffer().use { bufferedProcessSource ->
while (true) {
val line = bufferedProcessSource.readUtf8Line() ?: break
emit(line)
}
}
}
}.flowOn(<http://Dispatchers.IO|Dispatchers.IO>)
Florian
09/27/2020, 7:34 AM_taskUpdatedEvent
, which triggers the back navigation in the fragment. They navigate back from the screen after the insert operation is finished. Isn't this pretty similar to blocking the UI thread? It won't freeze the UI, but you can't actually do anything on that screen until the operation is finished and it's not really necessary to not navigate back immediately. I know that this operation will only take a few milliseconds but still, there is a reason why we execute queries on a background thread in the first place. Also, this could take longer depending on what happens in the repository. What is your opinion?
Edit: createTask
and updateTask
are suspending functionsAllan Wang
09/27/2020, 10:16 AMwithTimeoutOrNull(time) {
flow.collect { ... }
}
Is there a way to do this in the middle of the flow, such that the function still returns Flow<T>
?Animesh Sahu
09/27/2020, 1:04 PMval ch = BroadcastChannel<Int>(Channel.CONFLATED)
var counter = 0
ch.asFlow().onEach { ++counter; yield() }.launchIn(this)
ch.offer(150) // send random element
yield()
counter shouldBeExactly 1
this
in launchIn() is TestContext of kotest framework: https://github.com/kotest/kotest (probably single threaded)
but I assume yielding will change the coroutine to the waiting coroutine, right?Nemanja Scepanovic
09/28/2020, 7:55 AMCanellationException
would this completable deferred’s job be automatically completed or not? If not, what is the best way of making it cooperative?
Thanks 🙂Daniele Segato
09/28/2020, 9:05 AMsynchronize
keyword?
Synchronize lock access to the thread level. This means that if you call another fun that use the synchronize on the same object without jumping threads that fun doesn't block at the synchronize keyword.
With coroutines if you use a mutex in 2 fun and one call the other it creates a deadlock.
Is there something like a mutex that allow "children" coroutines of the lock holder go into the lock?Allan Wang
09/29/2020, 8:53 AMlaunch { … }.join()
and coroutineScope { }
?Pablo
09/29/2020, 12:29 PMviewModel
from now, so I don't have the coroutineScope on my presenter
and one way I'm doing right now is I'm injecting with Dagger
a CoroutineScope
as follows :
@Module
object CoroutineMainScopeModule{
@Provides
fun provideCoroutineMainScope() : CoroutineScope : MainScope()
}
But I don't know if I'd have problems in the future, cna someone let me know the disvantages of doing that way?
I also don't want to implement CoroutineScope
on the presenter because I read it's a bad praxis, neither use GlobalScope
.
I'm afraid because I don't have a Job
there, well I mean yes, I have a ContextScope(SupervisorJob() + Dispatchers.Main)
but in case I wanted to do things with different jobs, would be a problem there?mp911de
09/29/2020, 1:55 PM// variant 1: suspendable
val api: RedisClusterSuspendableCommands<String, String> = connection.suspendable()
// variant 2: coroutine
val api: RedisClusterCoroutineCommands<String, String> = connection.coroutine()
Tim Malseed
09/30/2020, 5:08 AMfun findSongs(): Flow<Pair<Song, Int>>
Where the flow emits a song, and a count of the total number of songs..
It seems a little redundant to have to emit the same ‘total’ each time. But the alternative is to have a separate function for retrieving the count, and thats’ not particularly efficient..spand
09/30/2020, 9:28 AMby lazy
variable with coroutines. I can call async(start = Lazy){ expensiveCalculation }
but afaik it does not make the computation optional, only delayed. What am I missing?Pablo
10/01/2020, 7:21 AMTestCoroutineScope.runBlockingTest{}
And
TestCoroutineDispatcher.runBlockingTest{}
I see some people use them, and others just put runBlockingText{}
without any dispatcher nor coroutineScope, is there any difference?Pablo
10/01/2020, 7:26 AMPablo
10/01/2020, 7:32 AMMainScope()
and I use it like :
@Inject constructor(
...
...
private val mainScope : CoroutineScope,
private val ioDispatcher: CoroutineDispatcher,
...
...
)
And then using it like this
mainScope.launch{
...
result withContext(ioDispatcher) {...}
...
}
If I do Dispatchers.setMain(TestCoroutineDispatcher())
does it change also the ioDispatcher
?
On my test I'm doing it like this :
private val testDispatcher = TestCoroutineDispatcher()
private val mainScope = TestCoroutineScope(testDispatcher)
And then on the @Before
I'm using this Dispatchers.setMain(testDispatcher)
And on every test I'm using
mainScope.runBlockingTest{...}
or
testDispatcher.runBlockingTest{...}
Is something I could improve?Se7eN
10/01/2020, 5:29 PMtemplatesDao.getAll().collectIndexed { index, templates ->
templatesLiveData.value = templates
if(index == 0) {
val newTemplates = getTemplatesFromFirestore(templates.lastIndex)
templatesDao.insert(newTemplates)
}
}
Is there any function like flow.onFirst { }
or something like thatansman
10/02/2020, 12:13 AMCoroutineDispatcher
that is an immediate behavior. I noticed that dispatchYield
is marked with @InternalCoroutinesApi
. Can someone confirm that this is there to prevent people from calling the method, not implementing it? Reading the documentation it seems that this is meant for custom dispatchers to implement but that you should avoid calling it manuallyBig Chungus
10/02/2020, 7:42 AMPablo
10/02/2020, 10:12 AMShashank
10/02/2020, 11:21 AMStateFlow
? If I have a data class
data class ProfileState(val isLoading: Boolean, val userName: String?)
and I have the following states which are being emitted
1. ProfileState(true, null)
2. ProfileState(false, “John Doe”)
So how do I that I received the states in the correct order while accounting for the conflation which is done by StateFlow
?Isaac
10/02/2020, 5:29 PMIsaac
10/02/2020, 5:29 PMRechee Jozil
10/02/2020, 9:49 PMIsaac
10/02/2020, 10:54 PMRechee Jozil
10/03/2020, 12:05 AMVipulyaara
10/04/2020, 9:10 AM