Skip to content

Commit 90755ef

Browse files
authored
Merge pull request #679 from synonymdev/fix/add-retry-defensive-check
chore: add defensive check to skip retry when node is starting
2 parents c558665 + 73b36e8 commit 90755ef

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

app/src/main/java/to/bitkit/repositories/LightningRepo.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ class LightningRepo @Inject constructor(
256256
scope.launch { registerForNotifications() }
257257
Unit
258258
}.onFailure { e ->
259+
val currentLifecycleState = _lightningState.value.nodeLifecycleState
260+
if (currentLifecycleState.isRunning()) {
261+
Logger.warn("Start error occurred but node is $currentLifecycleState, skipping retry", e, context = TAG)
262+
return@withContext Result.success(Unit)
263+
}
264+
259265
if (shouldRetry) {
260266
val retryDelay = 2.seconds
261267
Logger.warn("Start error, retrying after $retryDelay...", e, context = TAG)

app/src/test/java/to/bitkit/repositories/LightningRepoTest.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import org.mockito.kotlin.inOrder
2323
import org.mockito.kotlin.isNull
2424
import org.mockito.kotlin.mock
2525
import org.mockito.kotlin.spy
26+
import org.mockito.kotlin.times
2627
import org.mockito.kotlin.verify
2728
import org.mockito.kotlin.verifyBlocking
2829
import org.mockito.kotlin.whenever
@@ -646,4 +647,28 @@ class LightningRepoTest : BaseUnitTest() {
646647
assertTrue(result.isSuccess)
647648
verify(lightningService).setup(any(), anyOrNull(), anyOrNull(), isNull(), anyOrNull())
648649
}
650+
651+
@Test
652+
fun `start should not retry when node lifecycle state is Running`() = test {
653+
sut.setInitNodeLifecycleState()
654+
whenever(lightningService.node).thenReturn(null)
655+
whenever(lightningService.setup(any(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull())).thenReturn(Unit)
656+
whenever(settingsStore.data).thenReturn(flowOf(SettingsData()))
657+
val blocktank = mock<BlocktankService>()
658+
whenever(coreService.blocktank).thenReturn(blocktank)
659+
whenever(blocktank.info(any())).thenReturn(null)
660+
661+
// lightningService.start() succeeds (state becomes Running at line 241)
662+
whenever(lightningService.start(anyOrNull(), any())).thenReturn(Unit)
663+
// lightningService.nodeId throws during syncState() (called at line 244, AFTER state = Running)
664+
whenever(lightningService.nodeId).thenThrow(RuntimeException("error during syncState"))
665+
666+
val result = sut.start()
667+
668+
// Defensive check: state is Running, so don't retry, return success
669+
assertTrue(result.isSuccess)
670+
assertEquals(NodeLifecycleState.Running, sut.lightningState.value.nodeLifecycleState)
671+
// Verify start was only called once (no retry)
672+
verify(lightningService, times(1)).start(anyOrNull(), any())
673+
}
649674
}

0 commit comments

Comments
 (0)