F-Droid: serve an expired index as stale while refreshing in the background

Searches no longer wait for (or fail on) a refresh of an expired index; the
store notes which sources show saved listings. A failed refresh keeps the old
index and is retried after 10 minutes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
saphidandClaude Opus 5.5 committed 2026-09-28 22:11:04 +10:00
1 parent 7c439fdf28
commit 029c92bccb
6 files changed
+104 -14

No files matched your search

+10 -2
View File
@@ -87,9 +87,10 @@ class SearchTests(SettingsTest):
self.assertEqual(search.search('other', timeout=.03)['sources'][1]['status'], 'loading')
search.search('newest', timeout=.03)
self.assertEqual(calls, [''])
queued = search._pending['slow']
release.set()
result = search.search('newest', timeout=2)
self.assertEqual(result['sources'][1]['status'], 'ok')
self.assertTrue(queued['event'].wait(2))
self.assertEqual(queued['entries'], [])
self.assertEqual(calls, ['', 'newest']) # 'other' was superseded, never run
finally:
release.set()
@@ -106,6 +107,13 @@ class SearchTests(SettingsTest):
search.set_enabled('one', False)
self.assertEqual(free, [True])
def test_stale_source_status(self):
mod = fake()
mod.stale = lambda source: True
with patch.object(search, 'modules', return_value=([mod], [])):
status = search.search(timeout=1)['sources'][0]
self.assertEqual((status['status'], status['stale']), ('ok', True))
def test_limited_source_status(self):
from apk_sources import SourceLimited
mods = [fake('busy', Mock(side_effect=SourceLimited('busy is limiting requests', 60)))]