zt
08/24/2022, 3:57 AMval eventJob = launch {
while (true) {
val event = try {
when (val frame = incoming.receive()) {
is Frame.Text -> json.decodeFromString<Message.Event>(frame.readText())
is Frame.Close -> {
println("Received close frame: ${frame.readReason()}")
continue
}
else -> continue
}
} catch (e: Exception) {
println("Error while receiving: ${e.message}")
break
}
println("Received event: $event")
}
}
val heartbeatJob = launch {
while (true) {
delay(helloMessage.data.heartbeatInterval.milliseconds)
println("Sending heartbeat")
sendSerialized(Message.Heartbeat)
}
}
joinAll(eventJob, heartbeatJob)
Vikas Singh
08/24/2022, 9:13 AMLukas Lechner
08/24/2022, 11:27 AMPablo
08/25/2022, 10:13 AMJob
and then if the first finishes first cancel the second Job
to stop doing the work, also I think the way to do it is using launch{}
right? Instead of async {}
Lukas Lechner
08/25/2022, 1:30 PMflatMapMerge
and flatMapConcat
in regular application-specific flows, see attached image. What should we used instead when flatMapping two flows?Daniel Rodak
08/26/2022, 1:32 PMStateFlow
? So the case is that I have StateFlow
in my ViewModel
and I would like to launch some observation(e.g. User status Flow
) but I would like to stop this observation at the same moment that I will stop observing main StateFlow
itself so they need to be launched in the same scope. Currently I’m using combine with status observation flow but I’m ignoring events emitted by this Flow, is there a better way to handle it? Side not: I'm not using values emitted by the second flow directly so that's why I need to ignore them.turansky
08/30/2022, 11:07 AMhasNext
?
ChannelIterator has similar contractMark
08/31/2022, 10:30 AMcombine
but for when the flows (arguments) are calculated based on the item in the main flow? My use case is a flow of Item
s where each Item
has a number of properties whose values are provided by flows. Initially those properties are null and so the operator I’m trying to implement, would transform an Item
such that the properties are populated and the resulting Flow will emit a new Item
each time any of the properties updates (as well as when the original flow emits a new Item
).Tom Yuval
08/31/2022, 12:00 PMdelay(1)
in several places, to achieve just that: when any coroutine hits the delay(1)
its execution is suspended, allowing others to run (and complete or hitting delay(1)
themselves, allowing suspended coroutines to resume). And it generally seems to work. But it’s not elegant, and the delay itself, while not that noticeable, is not necessary.
Is there another way to do it? Something I can do at certain places in the code to allow a coroutine to suspend execution just in order to allow others to run until they complete or do the same?oday
08/31/2022, 1:26 PMTom Yuval
08/31/2022, 1:56 PMsuspend
functions, so I’m using kotlinx.coroutines.test.runTest
.
This has the useful feature of skipping `delay`s and simulating actual scheduling with virtual time, which is super useful as it allows the tests to run fast, and one can also control the order of execution of various parts of different coroutines very delicately.
However, I have a very specific use case where functions under test use `delay`s, and I actually want the `delay`s to execute for real, just like they would in production (this shouldn’t normally be required in pure unit tests, but is necessary in my case as the functions I’m testing interact with other systems). Is there a way to do that?Colton Idle
08/31/2022, 5:35 PMstate.myList.forEachIndexed { index, it ->
viewModelScope.launch {
it.isDone.value = apiService.isDone(it.id)
}
}
I thought I'd be able to add a .await()
to the end of the launch block to know when all of those parrallel api calls are done, but that doesn't compile.
Is there a more idiomatic way to do what I'm trying to do?oday
08/31/2022, 6:46 PMviewModelScope.launch(<http://dispatchers.io|dispatchers.io>) {
val filterSources = try {
listOf(
launch { getLocation.execute() },
launch { getCategory.execute() },
launch { getPeriod.execute() },
launch { getDateRange.execute() }
).joinAll().
} catch (e: Throwable) {
}
}
but unable to figure out how to get that to a map where i can use the stuff insideLilly
09/01/2022, 11:27 AModay
09/01/2022, 1:15 PMNicolas Verinaud
09/02/2022, 10:08 AMclass Sample(private val scope: CoroutineScope) {
private var currentJob: Job? = null
fun doSomeAsyncWork() {
currentJob?.cancel() // how to test this line ?
currentJob = scope.launch {
delay(5000)
}
}
}
Aditya Kurkure
09/03/2022, 4:44 AMZoltan Demant
09/04/2022, 4:37 AMDheeraj Singh Bhadoria
09/04/2022, 10:05 AMDheeraj Singh Bhadoria
09/04/2022, 10:10 AMsuspend fun getTopKeys(con: Context, rootObject: JSONObject): MutableLiveData<AuthResponse> {
return withContext(<http://Dispatchers.IO|Dispatchers.IO>){
val gson = Gson()
val accessToken = MyPrefConstant.getAccessToken(con)
val retrofit = RetrofitConfig.getRetrofitWithAccessToken(accessToken, con)
val service = retrofit?.create(ApiInterface::class.java)
var data = AesKotlin.encrypt(rootObject!!.toString(),AppConfig.ENCRYPTION_KEY)
Log.e("App1>>>>", data.replace("[\n]", "")!!.toString())
val call = service?.getTopKeys(data.replace("[\n]", "")!!.toString())
call?.enqueue(object : Callback<AuthResponse> {
override fun onResponse(call: Call<AuthResponse>, response: Response<AuthResponse>) {
if (response.code() == 200 && response.body().status.equals("OK")) {
val responseData = response.body()!!
searchData.value = gson.fromJson(gson.toJson(responseData), AuthResponse::class.java)
val i = Intent("return.apiResponse")
i.putExtra("data", gson.toJson(responseData).toString())
i.putExtra("method", "getTopN")
//con.sendBroadcast(i)
LocalBroadcastManager.getInstance(con).sendBroadcast(i)
}else{
// Toast.makeText(con, response.body().errorMessage, Toast.LENGTH_LONG).show()
val json = "{\"Status\": \"NOT OK\"," +
" \"ErrorMessage\": \"Something went wrong\" ," +
" \"Data\": \"NULL\", " +
" \"Timestamp\": \"NULL\" }"
searchData.value = gson.fromJson(json, AuthResponse::class.java)
}
}
override fun onFailure(call: Call<AuthResponse>, t: Throwable) {
Log.e("API","Error")
val json = "{\"Status\": \"NOT OK\"," +
" \"ErrorMessage\": \"Something went wrong \"," +
" \"Data\": \"NULL\", " +
" \"Timestamp\": \"NULL\" }"
searchData.value = gson.fromJson(json, AuthResponse::class.java)
}
})
searchData
}
}
In above method getTopKeys following methods are showing in mainthread in profiler
getJSON() - Related to gson
setValue - setting value to livedata
fromJSON - Related to gson
Dominaezzz
09/04/2022, 1:40 PMrunTest
not work with @BeforeTest
?oday
09/04/2022, 10:39 PMMain
Dispatchers called there? there’s no Main thread like UI dispatcher in kotlin itself https://hastebin.com/eyolacixis.propertiesKieran Wallbanks
09/05/2022, 4:31 PMrunBlocking
, I read that it shouldn't be used from a coroutine due to the potential for deadlocks (and we do seem to be encountering deadlocks here) but is there any way to "detect" if you're inside a coroutine somehow and run suspending methods in that coroutine instead of using runBlocking
? For reference, we're working inside a lot of pre-existing Java code that obviously can't be suspending, so I'm not sure how else to bridge it other than runBlocking
, which obviously isn't great and doesn't seem to be working for us.George
09/06/2022, 11:39 AMval account = async { getAccountByUuid(accountUUID) }
val devices = async { deviceRepository.findDevicesByUuid(accountUUID) }
account.await()?.addDevices(devices.await()) ?: return@coroutineScope null
In case the account.await() is null, the devices.await() is still waiting or it is just canceled ? I believe it is canceled but just want to make it sure. Thanks in advance for any answers !Trey
09/06/2022, 4:45 PMkenkyee
09/06/2022, 5:29 PMSam
09/08/2022, 7:59 AMinline fun <T> foo(f: nosuspend () -> T): T
Johnjake Talledo
09/12/2022, 5:05 AMdoAnotherCall()
, the viewModel.detailsState
collects in a loop. I mean its emit and collect
in a loop adding delay in doAnotherCall()
does not help. Best Regards.
private suspend fun collectProductList() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
viewLifecycleOwner.lifecycleScope.launch {
viewModel.detailsState.collectLatest { state ->
when (state) {
is ItemDetailState.ShowLoader -> binding.progressBar.visible()
is ItemDetailState.HideLoader -> binding.progressBar.gone()
is ItemDetailState.OnSuccess -> handleSubListSuccess(state.list, state.details)
is ItemDetailState.OnFailed -> handleFailure(state.error)
}
}
}
launch {
doAnotherCall()
}
}
pakoito
09/14/2022, 3:59 PMval pub = MutableSharedFlow<WorkJob>().apply {
onEach { println("Each") }
.onStart { println("Start") }
.onCompletion { println("Complete") }
.launchIn(GlobalScope)
}
...
somewhere else in code:
pub.tryEmit(WorkJob())
That triggers "start" but doesn't emit any value. The moment I put MutableSharedFlow<Job>(replay = 10)
it works, printing "start" and "each". But I want an infinite stream, not a repetition or something that goes to the latest value.Andrew Louis
09/15/2022, 3:34 AMAndrew Louis
09/15/2022, 3:34 AMPat Kujawa
09/17/2022, 12:19 AMKeith Miller
09/18/2022, 5:51 PM