1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-09-20 07:31:40 +02:00

Catch crashes, but things will still break

This commit is contained in:
Allan Wang 2019-01-22 23:41:14 -05:00
parent fa7c728071
commit bc623f740e
No known key found for this signature in database
GPG Key ID: C93E3F9C679D7A56
2 changed files with 60 additions and 44 deletions

View File

@ -16,11 +16,14 @@
*/
package com.pitchedapps.frost.kotlin
import com.pitchedapps.frost.utils.L
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
@ -64,57 +67,60 @@ class Flyweight<K, V>(
completeExceptionally(result.exceptionOrNull()!!)
}
private val errHandler = CoroutineExceptionHandler { _, throwable -> L.d { "FbAuth failed ${throwable.message}" } }
init {
job = scope.launch(Dispatchers.IO) {
launch {
while (isActive) {
select<Unit> {
/*
* New request received. Continuation should be fulfilled eventually
*/
actionChannel.onReceive { (key, completable) ->
val lastUpdate = conditionMap[key]
val lastResult = resultMap[key]
// Valid value, retrieved within acceptable time
if (lastResult != null && lastUpdate != null && System.currentTimeMillis() - lastUpdate < maxAge) {
completable.completeWith(lastResult)
} else {
val valueRequestPending = key in pendingMap
pendingMap.getOrPut(key) { mutableListOf() }.add(completable)
if (!valueRequestPending)
job =
scope.launch(Dispatchers.IO + SupervisorJob() + errHandler) {
launch {
while (isActive) {
select<Unit> {
/*
* New request received. Continuation should be fulfilled eventually
*/
actionChannel.onReceive { (key, completable) ->
val lastUpdate = conditionMap[key]
val lastResult = resultMap[key]
// Valid value, retrieved within acceptable time
if (lastResult != null && lastUpdate != null && System.currentTimeMillis() - lastUpdate < maxAge) {
completable.completeWith(lastResult)
} else {
val valueRequestPending = key in pendingMap
pendingMap.getOrPut(key) { mutableListOf() }.add(completable)
if (!valueRequestPending)
fulfill(key)
}
}
/*
* Invalidator received. Existing result associated with key should not be used.
* Note that any unfulfilled request and future requests should still operate, but with a new value.
*/
invalidatorChannel.onReceive { key ->
if (key !in resultMap) {
// Nothing to invalidate.
// If pending requests exist, they are already in the process of being updated.
return@onReceive
}
conditionMap.remove(key)
resultMap.remove(key)
if (pendingMap[key]?.isNotEmpty() == true)
// Refetch value for pending requests
fulfill(key)
}
}
/*
* Invalidator received. Existing result associated with key should not be used.
* Note that any unfulfilled request and future requests should still operate, but with a new value.
*/
invalidatorChannel.onReceive { key ->
if (key !in resultMap) {
// Nothing to invalidate.
// If pending requests exist, they are already in the process of being updated.
return@onReceive
}
conditionMap.remove(key)
resultMap.remove(key)
if (pendingMap[key]?.isNotEmpty() == true)
// Refetch value for pending requests
fulfill(key)
}
/*
* Value request fulfilled. Should now fulfill pending requests
*/
receiverChannel.onReceive { (key, result) ->
conditionMap[key] = System.currentTimeMillis()
resultMap[key] = result
pendingMap.remove(key)?.forEach {
it.completeWith(result)
/*
* Value request fulfilled. Should now fulfill pending requests
*/
receiverChannel.onReceive { (key, result) ->
conditionMap[key] = System.currentTimeMillis()
resultMap[key] = result
pendingMap.remove(key)?.forEach {
it.completeWith(result)
}
}
}
}
}
}
}
}
/*

View File

@ -27,9 +27,12 @@ import com.pitchedapps.frost.contracts.FrostContentContainer
import com.pitchedapps.frost.contracts.FrostContentCore
import com.pitchedapps.frost.contracts.FrostContentParent
import com.pitchedapps.frost.fragments.RecyclerContentContract
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
/**
* Created by Allan Wang on 2017-05-29.
@ -74,7 +77,14 @@ class FrostRecyclerView @JvmOverloads constructor(
if (Prefs.animate) fadeOut(onFinish = onReloadClear)
scope.launch {
parent.refreshChannel.offer(true)
val loaded = recyclerContract.reload { parent.progressChannel.offer(it) }
// TODO figure out how to avoid cancelling parent
try {
supervisorScope {
recyclerContract.reload { parent.progressChannel.offer(it) }
}
} catch (e: Exception) {
}
parent.progressChannel.offer(100)
parent.refreshChannel.offer(false)
if (Prefs.animate) circularReveal()