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

IllegalStateException : tryReleaseClaimedContinuation (DispatchedContinuation.kt:169) #3586

Closed
gittosuperfly opened this issue Jan 16, 2023 · 1 comment
Assignees
Labels

Comments

@gittosuperfly
Copy link

gittosuperfly commented Jan 16, 2023

Describe the bug

Errors are caught on firebase, and the number seems to be high .I caught >500 of these exceptions on firebase.
kotlinx-coroutines-core-jvm version = 1.5.0

log:

Caused by java.lang.IllegalStateException
Inconsistent state AwaitContinuation(DispatchedContinuation[Dispatchers.IO, Continuation at MyAppPackageName.xxxxx.ComponentLoader$download$3.invokeSuspend(ComponentLoader.kt)@5c61a13]){Active}@efd1450

kotlinx.coroutines.internal.DispatchedContinuation.tryReleaseClaimedContinuation (DispatchedContinuation.kt:169)
kotlinx.coroutines.CancellableContinuationImpl.releaseClaimedReusableContinuation (CancellableContinuationImpl.kt:323)
kotlinx.coroutines.CancellableContinuationImpl.getResult (CancellableContinuationImpl.kt:280)
kotlinx.coroutines.CancellableContinuationKt.suspendCancellableCoroutineReusable$$forInline (CancellableContinuationKt.java:331)
kotlinx.coroutines.sync.MutexImpl.lockSuspend (Mutex.kt:193)
kotlinx.coroutines.sync.MutexImpl.lock (Mutex.kt:190)
kotlinx.coroutines.sync.MutexKt.withLock$default (MutexKt.java:114)
MyAppPackageName.xxxxx.ComponentLoader$download$3.invokeSuspend (ComponentLoader.kt:134)
MyAppPackageName.xxxxx.ComponentLoader$download$3.invoke (ComponentLoader.kt:12)
kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn (Undispatched.kt:89)
kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext (Builders.common.kt:165)
kotlinx.coroutines.BuildersKt.withContext (BuildersKt.java:1)
MyAppPackageName.xxxxx.ComponentLoader.download (ComponentLoader.java:132)
MyAppPackageName.xxxxx.ComponentLoader$download$1.invokeSuspend (ComponentLoader.kt:114)
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106)
kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:571)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:678)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:665)

other log

Caused by java.lang.IllegalStateException
Job UndispatchedCoroutine{Cancelled}@df1b0f1 is already complete or completing, but is being completed with CompletedExceptionally[kotlinx.coroutines.JobCancellationException: Parent job is Cancelling; job=UndispatchedCoroutine{Cancelled}@df1b0f1]
kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core (JobSupport.kt:831)
kotlinx.coroutines.AbstractCoroutine.resumeWith (AbstractCoroutine.kt:100)
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:46)
kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:104)
kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:571)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:678)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:665)



Fatal Exception: kotlinx.coroutines.CoroutinesInternalError
Fatal exception in coroutines machinery for AwaitContinuation(DispatchedContinuation[Dispatchers.IO, Continuation at MyAppPackageName.ComponentLoader$download$3.invokeSuspend(ComponentLoader.kt)@5c61a13]){Cancelled}@efd1450. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
kotlinx.coroutines.DispatchedTask.handleFatalException (DispatchedTask.kt:144)
kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:115)
kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:571)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:678)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:665)

Provide a Reproducer

object ComponentLoader {

    private val coroutineScope: CoroutineScope by lazy {
        CoroutineScope(SupervisorJob() + Dispatchers.IO)
    }

    private val downloadMutexLock = Mutex()

    private val downloadingMap = ConcurrentHashMap<String, Job>()

    suspend fun loadAllTemplates(
        componentId: String,
        waitDownload: Boolean = true
    ): Map<String, ByteArray>? {
        return withContext(Dispatchers.IO) {
            if (waitDownload) {
                try {
                    downloadingMap[componentId]?.join()
                } catch (cancelExc: CancellationException) {
                    throw cancelExc
                }
            }
            getLocal(componentId)?.let {
                return@withContext it
            }
            return@withContext null
        }
    }

    @JvmStatic
    suspend fun download(
        componentId: String,
        cdnUrl: String
    ): SyncResult = withContext(Dispatchers.IO) {
        val deferred: Deferred<SyncResult>
        downloadMutexLock.withLock {
            if (downloadingMap.containsKey(componentId)) {
                val msg = "component $componentId is downloading..."
                return@withContext SyncResult.Error(componentId, Exception(msg))
            }
            if (checkLocalCacheAvailable(componentId, cdnUrl)) {
                return@withContext SyncResult.Success(componentId, false)
            }
            deferred = async(context = Dispatchers.IO, start = CoroutineStart.LAZY) {
                return@async downloadInternal(componentId, cdnUrl)
            }
            downloadingMap[componentId] = deferred
        }
        val result = deferred.await()
        downloadingMap.remove(componentId)
        return@withContext result
    }


    private suspend fun downloadInternal(componentId: String, cdnUrl: String): SyncResult {
        /**
         * one download logic...
         */
        return result
    }

    private suspend fun checkLocalCacheAvailable(
		componentId: String,
        cdnUrl: String
    ) = withContext(Dispatchers.IO) {
        /**
         * Check there is a cache locally
         */
		 return true or false
	}
}
@qwwdfsad qwwdfsad self-assigned this Jan 25, 2023
@qwwdfsad
Copy link
Member

The issue seems to have the same root cause as #2768 and is fixed starting from 1.5.1.

Please feel free to reopen if doesn't hold true

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

No branches or pull requests

2 participants