mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-22 07:06:05 +00:00
fix: stop reporting a Tor wait during the fetch, and serve the cache on
the rate limit that triggers the gate Addresses review on #812. The awaiting-route phase was never cleared. Reporting it before the wait fixed the label on the wait itself, but nothing restored ResolvingRelease afterwards, so the UI and notification claimed "Waiting for Tor" for the whole metadata request and its retries -- and in direct mode, where the wait returns immediately, for a wait that never happened. An onResolvingRelease callback now fires once the route is ready. A rate-limit rejection recorded the gate and returned the failure, while the stale-cache fallback sat at the top of the function and was only reached on a later call. The first About check therefore reported an error the user could not act on, and an immediate retry succeeded from metadata that was already present. The response that sets the gate now serves the cached release straight away. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f33ce0bb98
commit
b79ae8e7f1
@ -69,6 +69,7 @@ object GitHubReleaseClient {
|
||||
suspend fun fetchLatestRelease(
|
||||
forceRefresh: Boolean = false,
|
||||
onAwaitingNetworkRoute: (() -> Unit)? = null,
|
||||
onResolvingRelease: (() -> Unit)? = null,
|
||||
): Result<Release> =
|
||||
withContext(Dispatchers.IO) {
|
||||
fetchMutex.withLock {
|
||||
@ -108,6 +109,11 @@ object GitHubReleaseClient {
|
||||
)
|
||||
)
|
||||
}
|
||||
// The wait is over, so stop saying we are waiting. In direct mode it
|
||||
// returned immediately and never really started, and the fetch below
|
||||
// retries -- either way the caller must not keep reporting a Tor wait
|
||||
// for the whole metadata request.
|
||||
onResolvingRelease?.invoke()
|
||||
|
||||
var lastFailure: Throwable = ReleaseFetchException(
|
||||
"Failed to fetch the latest release from GitHub"
|
||||
@ -121,6 +127,18 @@ object GitHubReleaseClient {
|
||||
}
|
||||
lastFailure = result.exceptionOrNull() ?: lastFailure
|
||||
|
||||
// The response that just set the gate is the one the user is waiting
|
||||
// on. Reporting an error here and only serving the cache on the next
|
||||
// call makes the first check fail and an immediate retry succeed from
|
||||
// metadata we already had.
|
||||
if (System.currentTimeMillis() < blockedUntilMillis) {
|
||||
cached?.let {
|
||||
Log.w(TAG, "Rate limited; serving the cached release instead of failing")
|
||||
return@withLock Result.success(it.release)
|
||||
}
|
||||
return@withLock Result.failure(lastFailure)
|
||||
}
|
||||
|
||||
if (!isRetryable(lastFailure) || attempt == MAX_FETCH_ATTEMPTS - 1) {
|
||||
return@withLock Result.failure(lastFailure)
|
||||
}
|
||||
|
||||
@ -228,6 +228,9 @@ class UniversalApkManager(private val context: Context) {
|
||||
val release = GitHubReleaseClient.fetchLatestRelease(
|
||||
onAwaitingNetworkRoute = {
|
||||
phaseCallback?.invoke(ApkDownloader.DownloadPhase.AwaitingNetworkRoute)
|
||||
},
|
||||
onResolvingRelease = {
|
||||
phaseCallback?.invoke(ApkDownloader.DownloadPhase.ResolvingRelease)
|
||||
}
|
||||
).getOrElse { error ->
|
||||
return@withContext Result.failure(error)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user