feat: Update Android build workflow to run on Linux and enhance sync cycle handling in ProtocolManager

This commit is contained in:
2026-02-27 19:20:11 +05:00
parent 52efcdf111
commit b3c6acd007
2 changed files with 22 additions and 9 deletions

View File

@@ -14,7 +14,7 @@ on:
jobs:
build:
runs-on: android-builders
runs-on: linux
steps:
- name: Checkout code
uses: actions/checkout@v6

View File

@@ -550,6 +550,13 @@ object ProtocolManager {
subscribePushTokenIfAvailable()
}
private fun finishSyncCycle(reason: String) {
addLog(reason)
setSyncInProgress(false)
retryWaitingMessages()
requestMissingUserInfo()
}
/**
* Send FCM push token to server (SUBSCRIBE).
* Deduplicates: won't re-send the same token within one connection session.
@@ -689,6 +696,19 @@ object ProtocolManager {
else -> 0L
}
// Loop guard: if server keeps BATCH_END with unchanged cursor and we did not
// process anything in this batch, treat sync as finished to avoid infinite loop.
val noProgress =
failuresInBatch == 0 &&
processedMaxTimestamp <= 0L &&
(nextCursor <= 0L || nextCursor == currentCursor)
if (noProgress) {
finishSyncCycle(
"✅ SYNC COMPLETE — no progress on batch (server=$safeBatchTimestamp, current=$currentCursor)"
)
return@launch
}
// If server batch timestamp runs ahead of what we actually processed, clamp it.
// This avoids skipping tail messages when packet delivery/parsing was partial.
if (processedMaxTimestamp > 0L && processedMaxTimestamp < safeBatchTimestamp) {
@@ -709,18 +729,11 @@ object ProtocolManager {
}
}
SyncStatus.NOT_NEEDED -> {
addLog("✅ SYNC COMPLETE — no more messages to sync")
// Synchronous — immediately marks sync as complete.
// Desktop parity: NOT_NEEDED just sets state to CONNECTED,
// does NOT update last_sync timestamp (unnecessary since client
// was already up to date).
setSyncInProgress(false)
// Retry any messages stuck in WAITING status from previous sessions.
retryWaitingMessages()
// Desktop parity: resolve names for all dialogs with empty titles.
// Desktop does this per-component via useUserInformation hook;
// we batch it after sync for efficiency.
requestMissingUserInfo()
finishSyncCycle("✅ SYNC COMPLETE — no more messages to sync")
}
}
}