From 65ae792d5393fbfcc304ac683f54f6fcdca10a2c Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sun, 8 Nov 2026 20:38:55 +0000 Subject: Refresh on any connection; leave the download guard where it belongs Peter's mobile data is not metered, so the UNMETERED constraint on the refresh worker was doing nothing for him -- and the question was whether to mark the connection metered or drop the guard. Neither, quite. The guard was never about the cost of refreshing. Its own comment said so: "refreshing every feed is cheap, but downloads that follow are not". It was a proxy for a guard on downloads, and the refresh is genuinely cheap -- every request carries If-None-Match and If-Modified-Since, so an unchanged feed is a 304 with no body and a whole sweep is a few hundred bytes a show. Waiting for Wi-Fi to spend that is what let a failed refresh from hours earlier stay on screen as the current state of the library. So refresh runs on any connection now, and the download worker keeps its unmetered and battery-not-low constraints, which is where the expensive unattended work actually is. Marking the connection metered would have worked too, and is worse: it is a system-wide setting changed to compensate for one app, affecting every other app on the phone. **What the guard was really hiding, and still is:** anything reaching the queue calls Scheduling.downloadNow, which has no network constraint at all -- deliberately, because Peter asked for things he queues to download immediately including on mobile data. An auto-queue rule firing during a background refresh goes down that same path, so a rule can start tens of megabytes unattended on cellular. That is fine while his data is unmetered and is the real hole if it ever is not; distinguishing "I queued this" from "a rule queued this" is the fix, and it is not in this commit. 1059 tests, detekt 0. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B --- app/src/main/java/org/terst/listen/work/Workers.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/org/terst/listen/work/Workers.kt b/app/src/main/java/org/terst/listen/work/Workers.kt index 5e1bcad..88747fe 100644 --- a/app/src/main/java/org/terst/listen/work/Workers.kt +++ b/app/src/main/java/org/terst/listen/work/Workers.kt @@ -155,9 +155,17 @@ object Scheduling { PeriodicWorkRequestBuilder(REFRESH_HOURS, TimeUnit.HOURS) .setConstraints( Constraints.Builder() - // Unmetered: refreshing every feed is cheap, but downloads that follow - // are not, and a phone on mobile data should not discover that by itself. - .setRequiredNetworkType(NetworkType.UNMETERED) + // Any connection, not just unmetered. A refresh is conditional -- every + // request carries If-None-Match and If-Modified-Since -- so an unchanged + // feed is a 304 with no body, and a whole sweep is a few hundred bytes a + // show. Waiting for Wi-Fi to spend that leaves the library silently + // stale, which is how a failed refresh from hours ago came to be the + // thing on screen. + // + // This used to be UNMETERED, and the reason given was not the refresh + // itself: "downloads that follow are not [cheap]". That guard belongs on + // the downloads, and it is on them -- see DOWNLOAD_WORK below. + .setRequiredNetworkType(NetworkType.CONNECTED) .build() ) .build(), -- cgit v1.2.3