ghosalmartin
01/11/2022, 8:54 AMmarcinmoskala
01/11/2022, 9:03 AMMutableSharedFlow
? Seems that cancelling all listeners (so parent scope) is the only way for this program to close 😛
https://pl.kotl.in/EzyFeqARzTrevor Stone
01/11/2022, 5:26 PMSharingStarted.WhileSubscribed()
isn't working on 1.6.0-native-mt on iOSExerosis
01/11/2022, 10:24 PMdimsuz
01/13/2022, 9:25 AMCoroutineScope
and then I have dynamically created another scope, how could I add this scope to the first scope, so that second is cancelled along with the first?dimsuz
01/13/2022, 11:36 AMdrop(1)
makes subscriber loose first emitted item:
val flow = MutableSharedFlow<Int>(replay = 1)
fun get(replayLast: Boolean): Flow<Int> = flow.drop(1) // naive impl
launch { get(replayLast = false).collect { println(it} } } // doesn't receive 1
launch { delay(1000); flow.emit(1) }
Is having two separate flows: one with replay and one witout - the only option?Tower Guidev2
01/13/2022, 1:30 PMprivate val mutableDisplayedPageNoState = MutableSharedFlow<Int>(replay = 0, extraBufferCapacity = 3, onBufferOverflow = BufferOverflow.DROP_OLDEST)
bezrukov
01/14/2022, 2:22 PMThe Monster
01/15/2022, 2:53 PMscanAudios()
and scanVideos()
to execute first before other stuff in this function.
private suspend fun getFolderDataList(): List<FolderData> {
thisScope.async() {
scanAudios()
scanVideos()
}.await()
val audioFolderData = viewModel.getAudioUris().map { uri ->
FolderData("Audio", uri)
}
val videoFolderData = viewModel.getVideoUris().map { uri ->
FolderData("Video", uri)
}
return audioFolderData.plus(videoFolderData)
}
Am I doing it correctly?dimsuz
01/16/2022, 6:01 PMK Merle
01/17/2022, 5:45 AMcombine(
flowOne(),
flowTwo(),
flowThree()
) { _, _, flowThree->
flowThree
}.stateIn(
viewModelScope + ioDispatcher,
SharingStarted.WhileSubscribed(NETWORK_RESULT_SHARING_TIMEOUT),
Result.Loading
)
Should flowThree
emit values here when collected? FlowThree should emit every time flowOne() or flowTwo() emit values.benkuly
01/17/2022, 1:31 PMflow.flatMapLatest { flowValue ->
stateFlowDependingOnFlowValue(flow1Value,scope) // internally does something like `.stateIn(scope)`
}
Given this code, every time flatMapLatest
is called, a new coroutine is spawned in the scope. Is there a way to use a scope, which is only active within flatMapLatest
, so old calculations would be cancelled?dimsuz
01/18/2022, 5:52 PMPaul Woitaschek
01/18/2022, 9:42 PM/**
* This function returns once a shake was detected
*/
suspend fun detect() {
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager?
?: awaitCancellation()
val shakeDetected = CompletableDeferred<Unit>()
val listener = SeismicShakeDetector.Listener {
shakeDetected.complete(Unit)
}
val shakeDetector = SeismicShakeDetector(listener)
try {
shakeDetector.start(sensorManager)
shakeDetected.await()
} finally {
shakeDetector.stop()
}
}
I’ve written this function that suspend until a shake was detected. Do you think such a usage of coroutines makes sense?
It feels kind of unintuitive in terms of ergonomics of a regular functionNeil Marietta
01/19/2022, 10:19 AMubu
01/19/2022, 3:31 PMfun loadObject(id: Id) : Flow<Object>
fun subscribe(id: Id) : Flow<List<SubscriptionEvent>>
First, I tried to use combine
operator in the following manner:
loadObject(id).combine(subscribe(id)) { obj, events ->
var result = obj
events.forEach { event ->
result = when (event) {
is Init -> {
obj
}
is Amend -> {
result.amend(event.diff)
}
is Set -> {
event.data
}
is SubscriptionEvent.Unset -> {
result.unset(event.keys)
}
}
}
result
}
But this doesn’t work, obviously, since in the flow, there is always initial object (emitted only once after loading), which is combined with latest events / transformations, whereas what I need is something like scan
operator, where I could first initialize (load) my object, then start consuming events, which lead to the transformation of this object. Observers will receive something like: “object in initial state, after loaded”, “object with the first sets of transformations applied”, “object with the first and second set of transformations applied”.
Is there something like:
transformations.scan(initialObjectFlow) { latestVersionOfTheObject, events ->
// apply new events / transformations
// emit new version of the object
}
Thank you!natario1
01/19/2022, 4:30 PMval data: Flow<String?> = ....
val hasData: Flow<Boolean> = data.map { it != null }
val combined = data.combine(hasData) { data, hasData ->
require(data == null || hasData)
}
Note that hasData does not suspend, and let's assume flow will be collected on a single thread dispatcher.Stylianos Gakis
01/19/2022, 7:15 PMBrian Guertin
01/19/2022, 8:53 PMNSThread.stackSize
when using coroutines? Is NSThread even used? I'm trying to workaround a stack overflow in kotlinx.serialization. But how can I increase Worker stack size? Is it possible? https://youtrack.jetbrains.com/issue/KT-50870Stylianos Gakis
01/19/2022, 10:28 PMkotlinx.coroutines
is cancellable.
At first I thought at any suspension point, if the current context is cancelled it would not enter, but this wording makes it sound like it’s not like that.
Does this mean that potentially, if one made a series of suspending functions that are all not manually cooperating with cancellation (say all of them call blocking code, and/or other suspending functions that only call blocking code) cancellation would not happen and the suspending functions would keep alive?Jérémy CROS
01/21/2022, 1:53 PMrunTest
and it’s been an extremely frustrating process so far 😞
I have a very simple view model that doesn’t do a whole lot, something like :
fun registerStuff() {
viewModelScope.launch {
registerStuffUseCase.execute()
}
}
And a very simple test (with mockk)
@Before
fun setup() {
Dispatchers.setMain(StandardTestDispatcher())
}
@Test
fun `SHOULD fetch stuff WHEN called`() =
runTest {
// arrange
val registerStuffUseCase = mockk<RegisterStuffUseCase>(relaxed = true)
val viewModel = ViewModel(registerStuffUseCase)
// act
viewModel.registerStuff()
// assert
coVerify(exactly = 1) { registerStuffUseCase.execute() }
}
And it just doesn’t work. 100% of the time, verify is called before the use case is executed and the test fails.
* unless * I add a advanceUntillIdle()
after calling the VM...
Which I can do but that’s like a hundred tests to update and I’m not even sure I’m doing things properly...
Anything obvious I’m missing?pablisco
01/24/2022, 2:59 PMflow.flatMapLatest {
flow {
emit("a")
emit("b")
emitAll(otherFlow())
}
}
the same as this?
flow.transformLatest {
emit("a")
emit("b")
emitAll(otherFlow())
}
They seem to do the same on paper (minus the extra flow object), however, is there anything that using flatMapLatest
will do that transformLatest
doesn’t? 🙂brabo-hi
01/25/2022, 12:12 AMcallbackFlow
?
fun connect():Flow<Item> = callbackFlow {
check(1 == 0) // This is expected to throw an IllegalStateException
}
Lukasz Kalnik
01/25/2022, 1:07 PMclass Presenter(
val api: Api,
coroutineContext: CoroutineContext
) {
val coroutineScope = CoroutineScope(coroutineContext)
fun onAttachView(view View) {
coroutineScope.launch {
api.getDetail()
}
}
}
Test:
import io.mockk.*
class PresenterTest {
val testCoroutineScope = TestCoroutineScope()
val presenter = Presenter(
api = mockk(),
coroutineContext = testCoroutineScope.coroutineContext
)
val view = mockk()
@AfterEach
fun tearDown() {
testCoroutineScope.cleanupTestCoroutines()
}
@Test
fun `when view attached then call API`() {
presenter.test().attachView(view)
coVerify { api.getData() }
}
}
How do I migrate it to coroutine-test 1.6.0?Justin Tullgren
01/25/2022, 7:52 PMscope.launch { stateFlow.collect { if (it is State) doWork(); /* how do i unsubscribe here? */ } }
PHondogo
01/26/2022, 9:10 AMArun Joseph
01/26/2022, 3:56 PMhfhbd
01/26/2022, 5:13 PMnull
until b emits values. After b emits some values, the last value of b should be used (combine).Slackbot
01/26/2022, 8:59 PMubu
01/26/2022, 9:06 PMubu
01/26/2022, 9:06 PMephemient
01/26/2022, 9:08 PMubu
01/26/2022, 9:16 PMephemient
01/26/2022, 9:17 PM