Fix ClearLogsWorker never running and remove unsafe VACUUM

Three bugs:
- ExistingPeriodicWorkPolicy.REPLACE was resetting the 5-minute initial
  delay on every app start, so the worker never fired for users who open
  the app more than once before the delay expires. Changed to KEEP.
- No immediate cleanup meant existing accumulated data (e.g. 4GB) sat
  untouched until the periodic worker eventually ran. Added a one-time
  WorkRequest (ExistingWorkPolicy.KEEP) on every app start so cleanup
  runs right away.
- VACUUM on a multi-GB SQLite database requires equivalent free disk
  space as temp storage and blocks the DB for a long time — removed it.
  Row-level deletion via count/age caps is sufficient to control size.

https://claude.ai/code/session_01BCMhs2yA9XNUvfaX4sqsfv
This commit is contained in:
Claude
2026-04-01 12:52:28 +00:00
parent 725591a8f0
commit a8e9db9381
2 changed files with 21 additions and 10 deletions
@@ -14,6 +14,8 @@ import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import coil3.EventListener
@@ -207,18 +209,31 @@ class Amber :
}
private fun startCleanLogsAlarm() {
val workRequest = PeriodicWorkRequestBuilder<ClearLogsWorker>(
val workManager = WorkManager.getInstance(this)
// Run an immediate one-time cleanup on every startup to handle accumulated data.
// KEEP policy ensures only one instance runs at a time if the app is restarted quickly.
val immediateRequest = OneTimeWorkRequestBuilder<ClearLogsWorker>()
.addTag("clearLogsWorkOneTime")
.build()
workManager.enqueueUniqueWork(
"ClearLogsWorkerOneTime",
ExistingWorkPolicy.KEEP,
immediateRequest,
)
// Also schedule a daily periodic run.
// KEEP policy preserves the existing schedule so app restarts don't reset the timer.
val periodicRequest = PeriodicWorkRequestBuilder<ClearLogsWorker>(
24,
TimeUnit.HOURS,
)
.setInitialDelay(5, TimeUnit.MINUTES) // Delay first run by 5 minutes
.addTag("clearLogsWork")
.build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
workManager.enqueueUniquePeriodicWork(
"ClearLogsWorker",
ExistingPeriodicWorkPolicy.REPLACE,
workRequest,
ExistingPeriodicWorkPolicy.KEEP,
periodicRequest,
)
}
@@ -47,10 +47,6 @@ class ClearLogsWorker(appContext: Context, workerParams: WorkerParameters) : Cor
Log.d(Amber.TAG, "Trimmed $excessLogs excess log entries (cap: $MAX_LOG_ENTRIES)")
}
// Reclaim freed space from SQLite pages
logDatabase.openHelper.writableDatabase.execSQL("VACUUM")
historyDatabase.openHelper.writableDatabase.execSQL("VACUUM")
val database = Amber.instance.getDatabase(it.npub)
database.dao().updateExpiredPermissions(TimeUtils.now())
val deleted = database.dao().deleteOldApplications(now / 1000)