From 2eb737e8a0f5eeff3af4755baa68226ce07834f7 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 11 Aug 2026 10:03:42 -0300 Subject: [PATCH 1/3] feat: increase background stop debounce time --- app/src/main/java/to/bitkit/repositories/LightningRepo.kt | 7 ++++++- .../test/java/to/bitkit/repositories/LightningRepoTest.kt | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/to/bitkit/repositories/LightningRepo.kt b/app/src/main/java/to/bitkit/repositories/LightningRepo.kt index 728e878f5..7b5ca2e8f 100644 --- a/app/src/main/java/to/bitkit/repositories/LightningRepo.kt +++ b/app/src/main/java/to/bitkit/repositories/LightningRepo.kt @@ -585,6 +585,11 @@ class LightningRepo @Inject constructor( * Scheduling and cancelling are atomic: [cancelPendingStop] runs on the repo dispatcher while this * runs on the caller thread, so an interleaved cancel could otherwise miss the job being installed * and stop the node after the app is back in the foreground. + * + * [BACKGROUND_STOP_DELAY] plus the stop itself must stay under the cached-app freezer debounce + * (~10s once the process drops to `oom_adj` 900, which happens the moment the user opens another + * app). Past that the process is frozen mid-delay and the stop only fires on unfreeze, racing + * [cancelPendingStop] to tear the node down just as the user returns. */ fun stopDebounced() = synchronized(pendingStopLock) { val job = scope.launch { @@ -1896,7 +1901,7 @@ class LightningRepo @Inject constructor( private const val VSS_KEY_EXTERNAL_SCORES_CACHE = "external_pathfinding_scores_cache" private const val MS_SYNC_LOOP_DEBOUNCE = 500L private const val SYNC_RETRY_DELAY_MS = 15_000L - private val BACKGROUND_STOP_DELAY = 3.seconds + private val BACKGROUND_STOP_DELAY = 5.seconds private val CHANNELS_USABLE_TIMEOUT = 15.seconds private val NO_USABLE_CHANNELS_FEEDBACK_DELAY = 2_500.milliseconds val SEND_LN_TIMEOUT = 10.seconds diff --git a/app/src/test/java/to/bitkit/repositories/LightningRepoTest.kt b/app/src/test/java/to/bitkit/repositories/LightningRepoTest.kt index e40315dc4..76c9c99ad 100644 --- a/app/src/test/java/to/bitkit/repositories/LightningRepoTest.kt +++ b/app/src/test/java/to/bitkit/repositories/LightningRepoTest.kt @@ -88,7 +88,7 @@ import kotlin.time.Duration.Companion.seconds class LightningRepoTest : BaseUnitTest() { companion object { private const val NO_USABLE_CHANNELS_FEEDBACK_DELAY_MS = 2_500L - private const val BACKGROUND_STOP_DELAY_MS = 3_000L + private const val BACKGROUND_STOP_DELAY_MS = 5_000L } private lateinit var sut: LightningRepo From 52928941f7184316dc2bda64288ad361dddb0f85 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 11 Aug 2026 11:04:13 -0300 Subject: [PATCH 2/3] chore: update Kdoc comment --- .../java/to/bitkit/repositories/LightningRepo.kt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/to/bitkit/repositories/LightningRepo.kt b/app/src/main/java/to/bitkit/repositories/LightningRepo.kt index 7b5ca2e8f..3c45fba02 100644 --- a/app/src/main/java/to/bitkit/repositories/LightningRepo.kt +++ b/app/src/main/java/to/bitkit/repositories/LightningRepo.kt @@ -586,10 +586,16 @@ class LightningRepo @Inject constructor( * runs on the caller thread, so an interleaved cancel could otherwise miss the job being installed * and stop the node after the app is back in the foreground. * - * [BACKGROUND_STOP_DELAY] plus the stop itself must stay under the cached-app freezer debounce - * (~10s once the process drops to `oom_adj` 900, which happens the moment the user opens another - * app). Past that the process is frozen mid-delay and the stop only fires on unfreeze, racing - * [cancelPendingStop] to tear the node down just as the user returns. + * [BACKGROUND_STOP_DELAY] must stay under the cached-app freezer debounce (~10s once the process + * drops to `oom_adj` 900) so [stop] is at least entered before the process can be frozen. Past + * that the process freezes mid-delay and the stop only fires on unfreeze, racing + * [cancelPendingStop] to tear the node down just as the user returns — and [stop] runs + * `NonCancellable`, so losing that race is unrecoverable. + * + * Whether the stop *completes* in that window is out of scope here: on a wallet with real + * payment history ldk_node reliably hits its own 30s event-handling deadline, so no delay value + * makes the teardown fit. That also makes an avoided teardown valuable, since a user returning + * mid-stop waits it out before the ~8s node rebuild can start. */ fun stopDebounced() = synchronized(pendingStopLock) { val job = scope.launch { From 83c7451746d456d3ed797bcbc7fa93b67b711f1b Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 11 Aug 2026 11:06:21 -0300 Subject: [PATCH 3/3] doc: changelog --- changelog.d/next/1146.changed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/next/1146.changed.md diff --git a/changelog.d/next/1146.changed.md b/changelog.d/next/1146.changed.md new file mode 100644 index 000000000..8b2e27923 --- /dev/null +++ b/changelog.d/next/1146.changed.md @@ -0,0 +1 @@ +Bitkit now keeps the Lightning node running a little longer when you briefly leave the app, so quick trips to another app no longer reload the wallet on return.