mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-05 20:17:29 +00:00
feat(lotw): cancel in-flight sync, honest progress bar, drop stale hint
- Cancel: the dialog's cancel/back while syncing now aborts the download job (cooperative cancellation in the stream reader, CancellationException propagated, nothing written to storage). An accidental full sync can be stopped immediately. - Progress: the size estimate is conservative (900 B/record vs measured 720) so the bar never hits 100% before the download truly ends; storage writes moved to the IO dispatcher (multi-MB per-grid QSO JSON used to freeze the main thread after download); when the bar caps, the UI switches to 'Processing downloaded data…' instead of looking stuck. - Removed the outdated '3-10 seconds' hint (misleading for large accounts).
This commit is contained in:
1 parent
01ca06b43f
commit
5f1eb239ed
7 files changed
+55
-19
No files matched your search
+17
-5
@@ -22,7 +22,9 @@ import com.rtbishop.look4sat.core.domain.repository.LoTWPhase
|
||||
import com.rtbishop.look4sat.core.domain.repository.LoTWProgress
|
||||
import com.rtbishop.look4sat.core.domain.repository.LoTWResult
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.URL
|
||||
@@ -91,7 +93,7 @@ class LoTWRepository : ILoTWRepository {
|
||||
return Triple(grids, qsos, roamed)
|
||||
}
|
||||
|
||||
private fun fetchReportBody(
|
||||
private suspend fun fetchReportBody(
|
||||
callsign: String,
|
||||
password: String,
|
||||
since: String,
|
||||
@@ -151,6 +153,9 @@ class LoTWRepository : ILoTWRepository {
|
||||
!body.contains("<eoh>", ignoreCase = true) -> Result.failure(RateLimitException())
|
||||
else -> Result.success(body)
|
||||
}
|
||||
} catch (e: java.util.concurrent.CancellationException) {
|
||||
// Cancellation must propagate — it is not a network failure.
|
||||
throw e
|
||||
} catch (e: SocketTimeoutException) {
|
||||
Result.failure(TimeoutException(e.message ?: "timed out"))
|
||||
} catch (e: SSLException) {
|
||||
@@ -167,7 +172,7 @@ class LoTWRepository : ILoTWRepository {
|
||||
* body size is estimated as NUMREC * AVG_RECORD_BYTES so the UI can show a
|
||||
* meaningful progress bar and remaining-time estimate.
|
||||
*/
|
||||
private fun readBodyWithProgress(
|
||||
private suspend fun readBodyWithProgress(
|
||||
stream: java.io.InputStream,
|
||||
isGzip: Boolean,
|
||||
onProgress: (LoTWProgress) -> Unit
|
||||
@@ -185,6 +190,11 @@ class LoTWRepository : ILoTWRepository {
|
||||
var lastSampleBytes = 0L
|
||||
var lastEmitMs = 0L
|
||||
while (true) {
|
||||
// Cooperative cancellation: lets the user abort a full sync that
|
||||
// was started by mistake. Throws CancellationException once the
|
||||
// job is cancelled; the blocking read below is fast while chunks
|
||||
// keep arriving, so the abort lands on the next chunk boundary.
|
||||
coroutineContext.ensureActive()
|
||||
val n = reader.read(buf)
|
||||
if (n <= 0) break
|
||||
sb.append(buf, 0, n)
|
||||
@@ -440,9 +450,11 @@ class LoTWRepository : ILoTWRepository {
|
||||
val NUMREC_REGEX = Regex("<APP_LoTW_NUMREC:\\d+>(\\d+)")
|
||||
/**
|
||||
* Measured 2026-09-16 (BH6RJD, 2367 QSLs): 1.7 MB body streamed at
|
||||
* ~9.5 KB/s ≈ 180 s, i.e. ≈ 720 bytes per ADIF record. Used to predict
|
||||
* the total body size from the header record count.
|
||||
* ~9.5 KB/s ≈ 180 s, i.e. ≈ 720 bytes per ADIF record. Use a
|
||||
* CONSERVATIVE (larger) estimate so the progress bar never hits 100%
|
||||
* before the download truly ends — an under-estimate made the bar sit
|
||||
* at 100% while data was still flowing, read as "finished but stuck".
|
||||
*/
|
||||
const val AVG_RECORD_BYTES = 720L
|
||||
const val AVG_RECORD_BYTES = 900L
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,6 @@
|
||||
<string name="prefs_lotw_callsign">LoTW 呼号</string>
|
||||
<string name="prefs_lotw_password">LoTW 密码</string>
|
||||
<string name="prefs_lotw_hint">直接从 ARRL LoTW 拉取该呼号已确认 QSO 的网格并覆盖本地已存集合(当前 %1$d 个)。密码仅保存在手机本地。点"同步"会自动保存凭据并拉取。</string>
|
||||
<string name="prefs_lotw_sync_duration_hint">同步通常约需 3–10 秒;首次同步或 ARRL 服务器繁忙时可能更久。</string>
|
||||
<string name="prefs_lotw_sync">同步</string>
|
||||
<string name="prefs_lotw_syncing">同步中…</string>
|
||||
<string name="prefs_lotw_configured">已从 LoTW 同步 — 共 %1$d 个网格</string>
|
||||
@@ -175,6 +174,7 @@
|
||||
<string name="lotw_sync_rate_hint">下载速度约每 100 条 QSO 需 8 秒(另有 5–40 秒服务器生成时间)</string>
|
||||
<string name="lotw_sync_progress_connecting">正在连接 LoTW 服务器…</string>
|
||||
<string name="lotw_sync_progress_downloading">正在下载报告…</string>
|
||||
<string name="lotw_sync_progress_saving">正在处理下载的数据…</string>
|
||||
<string name="lotw_sync_progress_count">本次同步 %1$d 条 QSO…</string>
|
||||
<string name="lotw_sync_progress_qso">本次同步 %1$d 条 QSO,预计还需 %2$d 秒</string>
|
||||
<string name="prefs_locator_text">使用梅登黑德网格设置站点位置</string>
|
||||
|
||||
@@ -195,7 +195,6 @@
|
||||
<string name="prefs_lotw_callsign">LoTW callsign</string>
|
||||
<string name="prefs_lotw_password">LoTW password</string>
|
||||
<string name="prefs_lotw_hint">Fetch confirmed-QSO grids directly from ARRL LoTW for this callsign and replace the stored set (currently %1$d). The password is stored on this device only. Tapping Sync saves the credentials and fetches in one step.</string>
|
||||
<string name="prefs_lotw_sync_duration_hint">A sync usually takes about 3–10 seconds; the first one or a busy ARRL server can take longer.</string>
|
||||
<string name="prefs_lotw_sync">Sync</string>
|
||||
<string name="prefs_lotw_syncing">Syncing…</string>
|
||||
<string name="prefs_lotw_configured">Synced from LoTW — %1$d grids total</string>
|
||||
@@ -210,6 +209,7 @@
|
||||
<string name="lotw_sync_rate_hint">Download runs at ~8 s per 100 QSOs (plus 5–40 s server generation time)</string>
|
||||
<string name="lotw_sync_progress_connecting">Connecting to LoTW…</string>
|
||||
<string name="lotw_sync_progress_downloading">Downloading report…</string>
|
||||
<string name="lotw_sync_progress_saving">Processing downloaded data…</string>
|
||||
<string name="lotw_sync_progress_count">Syncing %1$d QSOs…</string>
|
||||
<string name="lotw_sync_progress_qso">Syncing %1$d QSOs, ~%2$d s remaining</string>
|
||||
<string name="prefs_locator_text">Set station\'s position using locator</string>
|
||||
|
||||
Reference in new issue
Block a user