Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CoroutinesInternalError - Job is already complete or completing #1743

Closed
kaserdan opened this issue Jan 2, 2020 · 16 comments
Closed

CoroutinesInternalError - Job is already complete or completing #1743

kaserdan opened this issue Jan 2, 2020 · 16 comments

Comments

@kaserdan
Copy link

kaserdan commented Jan 2, 2020

I have updated to the latest version of coroutines 1.3.3 and weird crash started popping in crashlytics. The weird thing is that all crashes are happening only on devices with Android 7.0 (about 5.5 % of users) and another common thing for these devices seems to be MediaTek SoC.

It seems to have someting to do with combine so I will look into that. Any help is appreciated

Fatal Exception: kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[LimitingDispatcher@afe7038[dispatcher = DefaultDispatcher], Continuation at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2$invokeSuspend$$inlined$select$lambda$2@f78b196]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
       at kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx_coroutines_core + 278(DispatchedTask.java:278)
       at kotlinx.coroutines.DispatchedTask.run + 249(DispatchedTask.java:249)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely + 594(CoroutineScheduler.java:594)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely + 60(CoroutineScheduler.java:60)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run + 740(CoroutineScheduler.java:740)
Caused by java.lang.IllegalStateException: Job ScopeCoroutine{Completed}@c55549b is already complete or completing, but is being completed with kotlin.Unit
       at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core + 788(JobSupport.java:788)
       at kotlinx.coroutines.AbstractCoroutine.resumeWith + 111(AbstractCoroutine.java:111)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith + 46(BaseContinuationImpl.java:46)
       at kotlinx.coroutines.selects.SelectBuilderImpl.resumeWith + 254(SelectBuilderImpl.java:254)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith + 46(BaseContinuationImpl.java:46)
       at kotlinx.coroutines.DispatchedTask.run + 241(DispatchedTask.java:241)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely + 594(CoroutineScheduler.java:594)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely + 60(CoroutineScheduler.java:60)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run + 740(CoroutineScheduler.java:740)
@qwwdfsad
Copy link
Member

qwwdfsad commented Jan 2, 2020

It's hard to tell what exactly is wrong.
Usually, such an error indicates that the underlying continuation was resumed twice, but why exactly this is happening is hard to tell without repro (or, at least, more details).
combine is a pretty good suspect as it uses select operator internally that was seriously reworked in 1.3.3. Could you please provide a snippet of how combine is used? It shouldn't be self-contained, but just to get the idea: what other operators are used, what dispatcher is used, whether it is really used concurrently on not etc.

@kaserdan
Copy link
Author

kaserdan commented Jan 3, 2020

I am using combine to lazy load items, that are not available immidetaly and then kind of map these items to cartContent. Could the flatMapLatest be the cause of "is already complete or completing"?

Fetching items

    fun fetchAllItems(): Flow<List<ItemsWithCount>> =
        combine(
            flow {
                val partialData: List<Items> = fetchPartialData()
                // emit items I got immidietaly, to show at least something
                emit(partialData.filterNot { it.notLoaded })
                // check if there are any items, that need to be loaded lazily
                if (partialData.any { it.notLoaded }) {
                    combine(getSourcesToLoad(partialData)) { loaded ->
                        // combine them into List<Items> with all items loaded
                    }.collect { emit(it) }
                }
            },
            cartContentFlow
        ) { items, cartContent ->
            // map items to cart content to show count, price etc...
        }.flowOn(Dispatchers.IO)

And then I am waiting for events from view to load items, something like this:

merge(events.filterIsInstance<ViewInitialized>(), events.filterIsInstance<ReloadClicked>())
   .flatMapLatest { fetchAllItems()}
   .collect { updateItems(it) }

@qwwdfsad
Copy link
Member

could you please clarify whether this problem is still reproducible on the latest version of coroutines?

@kaserdan
Copy link
Author

kaserdan commented Mar 13, 2020

I have ditched the combine operator for this case, that actually helped. I will try to revert back to the same code with the version 1.3.4. Since I don't know any way to reproduce these errors, I will just keep watching crashlytics.

@ReginFell
Copy link

The same error happens to a few of our users on the version 1.3.4 as well.
And what is really weird, that only users with Android 7 are affected.

The problem that we are actively using flow and the crashlogs do not show any specific place which could throw this exception

Fatal Exception: kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[Main [immediate], Continuation at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Combine.kt)@4470cff]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
       at kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx_coroutines_core(DispatchedTask.java:93)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:64)
       at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.java:69)
       at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuationKt.java:321)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(CancellableKt.java:26)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.java:109)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.java:158)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_commonKt.java:54)
       at kotlinx.coroutines.BuildersKt.launch(BuildersKt.java:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_commonKt.java:47)
       at kotlinx.coroutines.BuildersKt.launch$default(BuildersKt.java:1)
       at androidx.lifecycle.BlockRunner.maybeRun(BlockRunner.java:174)
Caused by java.lang.IllegalStateException: Job ScopeCoroutine{Cancelled}@145a4a0 is already complete or completing, but is being completed with CompletedExceptionally[kotlinx.coroutines.JobCancellationException: ScopeCoroutine is cancelling; job=ScopeCoroutine{Cancelled}@145a4a0]
       at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.java:828)
       at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.java:111)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:46)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:55)
       at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.java:69)
       at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuationKt.java:321)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(CancellableKt.java:26)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.java:109)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.java:158)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_commonKt.java:54)
       at kotlinx.coroutines.BuildersKt.launch(BuildersKt.java:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_commonKt.java:47)
       at kotlinx.coroutines.BuildersKt.launch$default(BuildersKt.java:1)

@MattSkala
Copy link

We are seeing the same crash on Android 7 with coroutines 1.3.3. I'm posting the full stack trace. The interesting thing is that the crash is probably triggered by OutOfMemoryException and it only happens on Android 7.0 and 7.1.

Fatal Exception: kotlinx.coroutines.l0
Fatal exception in coroutines machinery for DispatchedContinuation[Main [immediate], Continuation at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Combine.kt)@66c6a13]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
Fatal Exception: kotlinx.coroutines.l0: Fatal exception in coroutines machinery for DispatchedContinuation[Main [immediate], Continuation at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Combine.kt)@66c6a13]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
       at kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx_coroutines_core(DispatchedTask.java:93)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:64)
       at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.java:68)
       at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuationKt.java:320)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(CancellableKt.java:26)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.java:109)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.java:158)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_commonKt.java:54)
       at kotlinx.coroutines.BuildersKt.launch(BuildersKt.java:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_commonKt.java:47)
       at kotlinx.coroutines.BuildersKt.launch$default(BuildersKt.java:1)
       at androidx.lifecycle.BlockRunner.maybeRun(BlockRunner.java:174)
       at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.java:240)
       at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
       at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:395)
       at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
       at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
       at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
       at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
       at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
       at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:51)
       at androidx.fragment.app.Fragment.performStart(Fragment.java:2737)
       at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
       at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
       at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
       at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258)
       at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550)
       at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
       at android.app.Activity.performStart(Activity.java:6733)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2687)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
       at android.os.Handler.dispatchMessage(Handler.java:110)
       at android.os.Looper.loop(Looper.java:203)
       at android.app.ActivityThread.main(ActivityThread.java:6251)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by java.lang.IllegalStateException
Job v{Cancelled}@6db0de4 is already complete or completing, but is being completed with v[kotlinx.coroutines.JobCancellationException: v is cancelling; job=v{Cancelled}@6db0de4]
Caused by java.lang.IllegalStateException: Job v{Cancelled}@6db0de4 is already complete or completing, but is being completed with v[kotlinx.coroutines.JobCancellationException: v is cancelling; job=v{Cancelled}@6db0de4]
       at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.java:827)
       at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.java:111)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:46)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:55)
       at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.java:68)
       at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuationKt.java:320)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(CancellableKt.java:26)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.java:109)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.java:158)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_commonKt.java:54)
       at kotlinx.coroutines.BuildersKt.launch(BuildersKt.java:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_commonKt.java:47)
       at kotlinx.coroutines.BuildersKt.launch$default(BuildersKt.java:1)
       at androidx.lifecycle.BlockRunner.maybeRun(BlockRunner.java:174)
       at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.java:240)
       at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
       at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:395)
       at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
       at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
       at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
       at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
       at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
       at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:51)
       at androidx.fragment.app.Fragment.performStart(Fragment.java:2737)
       at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
       at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
       at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
       at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258)
       at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550)
       at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
       at android.app.Activity.performStart(Activity.java:6733)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2687)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
       at android.os.Handler.dispatchMessage(Handler.java:110)
       at android.os.Looper.loop(Looper.java:203)
       at android.app.ActivityThread.main(ActivityThread.java:6251)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by kotlinx.coroutines.JobCancellationException
v is cancelling
Caused by kotlinx.coroutines.JobCancellationException: v is cancelling

Caused by java.lang.OutOfMemoryError
Failed to allocate a 72 byte allocation with 4194304 free bytes and 8MB until OOM; failed due to fragmentation (required continguous free 4096 bytes for a new buffer where largest contiguous free 0 bytes)
Caused by java.lang.OutOfMemoryError: Failed to allocate a 72 byte allocation with 4194304 free bytes and 8MB until OOM; failed due to fragmentation (required continguous free 4096 bytes for a new buffer where largest contiguous free 0 bytes)
       at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(CombineKt.java:149)
       at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invoke(CombineKt.java)
       at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(UndispatchedKt.java:91)
       at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScopeKt.java:177)
       at kotlinx.coroutines.flow.internal.CombineKt.combineInternal(CombineKt.java:52)
       at com.fitifyapps.fitify.ui.plans.planday.PlanDayViewModel$items$2$$special$$inlined$combine$1.collect(PlanDayViewModel.java:126)
       at androidx.lifecycle.FlowLiveDataConversions$asLiveData$1.invokeSuspend(FlowLiveDataConversions.java:139)
       at androidx.lifecycle.FlowLiveDataConversions$asLiveData$1.invoke(FlowLiveDataConversions.java)
       at androidx.lifecycle.BlockRunner$maybeRun$1.invokeSuspend(BlockRunner.java:176)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:33)
       at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuationKt.java:313)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(CancellableKt.java:26)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.java:109)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.java:158)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_commonKt.java:54)
       at kotlinx.coroutines.BuildersKt.launch(BuildersKt.java:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_commonKt.java:47)
       at kotlinx.coroutines.BuildersKt.launch$default(BuildersKt.java:1)
       at androidx.lifecycle.BlockRunner.maybeRun(BlockRunner.java:174)
       at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.java:240)
       at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
       at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:395)
       at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
       at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
       at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
       at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
       at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
       at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:51)
       at androidx.fragment.app.Fragment.performStart(Fragment.java:2737)
       at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
       at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
       at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
       at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258)
       at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550)
       at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
       at android.app.Activity.performStart(Activity.java:6733)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2687)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
       at android.app.ActivityThread.-wrap12(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
       at android.os.Handler.dispatchMessage(Handler.java:110)
       at android.os.Looper.loop(Looper.java:203)
       at android.app.ActivityThread.main(ActivityThread.java:6251)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

@asfdfdfd
Copy link

asfdfdfd commented Jul 31, 2020

I have this issue on 1.3.6 version.

My typical "combine" usage is something like this:

val flow1 = dao.selectData().filterNotNull().distinctUntilChanged()
val flow2 = dao.selectData().filterNotNull().distinctUntilChanged()

flow1.combine(flow2) { f1, f2 -> (f1 to f2) }.collect {  }

Sometimes "conflate" added to the source flows. And sometimes i use "collectLatest" instead of "collect"

@qwwdfsad
Copy link
Member

qwwdfsad commented Aug 3, 2020

It seems to be a duplicate of #1683, and, to be more detailed, of vendor issue https://issuetracker.google.com/issues/145569946

It would be really nice if anyone could check the crossinline hypothesis and verify that replacing combine(a, b) {} with a.combine(b) {} solves the issue.

Unfortunately, we cannot even provide a "safer" mechanism as long as we cannot reproduce it locally.
If anyone could point a precise device model that is able to reproduce the problem manually via ADP (along with a reproducer), it could also help as we can order such device and investigate potential workarounds.

@minyushov
Copy link

I was able to reproduce the issue on Meizu M6 (M711H). Unfortunately, I don't have this device now and can't verify the workaround above.

@asfdfdfd
Copy link

asfdfdfd commented Aug 3, 2020

It would be really nice if anyone could check the crossinline hypothesis and verify that replacing combine(a, b) {} with a.combine(b) {} solves the issue.

I'm going to try this in the next release of our app.

@asfdfdfd
Copy link

@qwwdfsad

App is in production almost for a week and has not discussed crash after replacing combine(a, b) {} with a.combine(b) {}.

@qwwdfsad
Copy link
Member

Great! So the workaround is know, that's good.
Still looking for feedback regarding hardware devices that were able to reproduce the problem with ADP

@mhernand40
Copy link

Although several device manufacturers are able to reproduce this issue, OPPO devices seem to be the most prevalent. Here is a screenshot of the reproducing OPPO devices from my Firebase Crashlytics dashboard:

Screen Shot 2020-08-14 at 1 51 14 PM

Where the stack trace is:

Fatal Exception: kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[Dispatchers.Default, Continuation at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Combine.kt)@903cd9f]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
       at kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx_coroutines_core(DispatchedTask.java:93)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:64)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:571)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.java:738)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.java:678)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.java:665)
Caused by java.lang.ClassCastException: kotlin.coroutines.jvm.internal.CompletedContinuation cannot be cast to kotlinx.coroutines.DispatchedContinuation
       at kotlinx.coroutines.CoroutineDispatcher.releaseInterceptedContinuation(CoroutineDispatcher.java:103)
       at kotlin.coroutines.jvm.internal.ContinuationImpl.releaseIntercepted(ContinuationImpl.java:118)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:39)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:56)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:571)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.java:738)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.java:678)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.java:665)

@YarnSphere
Copy link

For a change of scenery, I'm not encountering this in Andoid but while testing a build produced by the new JS-IR compiler (code works fine in both JVM and legacy JS):

CoroutinesInternalError: Fatal exception in coroutines machinery for CancellableContinuation(DispatchedContinuation[NodeDispatcher@2, [object Object]]){kotlin.Unit}@3. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
    at CancellableContinuationImpl.DispatchedTask.handleFatalException_2 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:31729:18)
    at CancellableContinuationImpl.DispatchedTask.run_40 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:31720:12)
    at ScheduledMessageQueue.MessageQueue.process_1 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:32887:21)
    at _no_name_provided__116.invoke_400 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:33030:20)
    at /path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:32980:9
    at processTicksAndRejections (internal/process/task_queues.js:79:11) {
  message: "Fatal exception in coroutines machinery for CancellableContinuation(DispatchedContinuation[NodeDispatcher@2, [object Object]]){kotlin.Unit}@3. Please read KDoc to 'handleFatalException' method and report this incident to maintainers",
  cause: IllegalStateException: Job StandaloneCoroutine{Completed}@1 is already complete or completing, but is being completed with kotlin.Unit
      at StandaloneCoroutine.JobSupport.makeCompletingOnce_14 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:23242:17)
      at StandaloneCoroutine.AbstractCoroutine.resumeWith_58 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:20779:22)
      at $emit_2COROUTINE$72.CoroutineImpl_0.resumeWith_233 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:18532:26)
      at $emit_2COROUTINE$72.CoroutineImpl_0.resumeWith_58 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:18540:17)
      at ScopeCoroutine.afterResume_10 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:32000:17)
      at ScopeCoroutine.AbstractCoroutine.resumeWith_58 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:20782:10)
      at _no_name_provided__155.CoroutineImpl_0.resumeWith_233 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:18532:26)
      at _no_name_provided__155.CoroutineImpl_0.resumeWith_58 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:18540:17)
      at CancellableContinuationImpl.DispatchedTask.run_40 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:31689:24)
      at ScheduledMessageQueue.MessageQueue.process_1 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:32887:21)
      at _no_name_provided__116.invoke_400 (/path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:33030:20)
      at /path/to/lib-jsIr-test/kotlin/Lib-name-jsIr-test.js:32980:9
      at processTicksAndRejections (internal/process/task_queues.js:79:11) {
    message: 'Job StandaloneCoroutine{Completed}@1 is already complete or completing, but is being completed with kotlin.Unit',
    cause: null,
    name: 'IllegalStateException'
  },
  name: 'CoroutinesInternalError'
}

So far I'm having some trouble isolating or working around the issue (I don't use any combine or select in my code). Should I open a new ticket or do you think these are related?

@Samhithgb
Copy link

Samhithgb commented Sep 18, 2020

FYI,
Had the same issue when running unit test on Android, and using a single thread test dispatcher fixed the issue for me :

private val testDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()

during setup :
Dispatchers.setMain(testDispatcher)

and then in tear up :
Dispatchers.resetMain() testDispatcher.close()

@ReginFell
Copy link

Any news related to this issue? combine is completely unreliable since it randomly crashes on some android devices

qwwdfsad added a commit that referenced this issue Oct 19, 2020
    * Do not allocate array on each transform call in combine, do it only for combineTransform
    * Simplify zip operator even further
    * Get rid of crossinline in combine to fix weird Android crashes

Fixes #1743
Fixes #1683
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants