mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
fix(marmot): a Welcome that ran out of retries waits for the next app start
Relays re-deliver two days of gift wraps on every re-subscription, and each delivery of a Welcome that kept failing started a fresh 30s/2m/10m chain, so a Welcome that can never apply was re-run through MLS for as long as relays kept it. Exhausted Welcomes are now remembered for the session: re-deliveries skip them, and the next app start still gives them one more try. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
90264a815d
commit
0c9f4cbf0b
@@ -94,10 +94,25 @@ class AccountMarmotActions(
|
||||
// Welcome rumor ids with a retry already scheduled, so a relay re-delivering the same
|
||||
// wrap while one waits does not start a second chain of retries.
|
||||
private val welcomeRetries = mutableSetOf<HexKey>()
|
||||
|
||||
// Welcome rumor ids whose retries ran out this session. Relays re-deliver two days of gift
|
||||
// wraps on every re-subscription, and each delivery used to start a fresh chain, so a
|
||||
// Welcome that can never apply was re-run through MLS for as long as relays kept it.
|
||||
// In memory on purpose: the next app start still gives it one more try.
|
||||
private val welcomeRetriesExhausted = mutableSetOf<HexKey>()
|
||||
private val welcomeRetriesLock = KmpLock()
|
||||
|
||||
/** True when [welcomeId] had no retry pending and now has one. */
|
||||
fun claimWelcomeRetry(welcomeId: HexKey): Boolean = welcomeRetriesLock.withLock { welcomeRetries.add(welcomeId) }
|
||||
/** True when [welcomeId] had no retry pending, has retries left, and now has one pending. */
|
||||
fun claimWelcomeRetry(welcomeId: HexKey): Boolean =
|
||||
welcomeRetriesLock.withLock {
|
||||
welcomeId !in welcomeRetriesExhausted && welcomeRetries.add(welcomeId)
|
||||
}
|
||||
|
||||
fun markWelcomeRetriesExhausted(welcomeId: HexKey) {
|
||||
welcomeRetriesLock.withLock { welcomeRetriesExhausted.add(welcomeId) }
|
||||
}
|
||||
|
||||
fun welcomeRetriesExhausted(welcomeId: HexKey): Boolean = welcomeRetriesLock.withLock { welcomeId in welcomeRetriesExhausted }
|
||||
|
||||
fun releaseWelcomeRetry(welcomeId: HexKey) {
|
||||
welcomeRetriesLock.withLock { welcomeRetries.remove(welcomeId) }
|
||||
|
||||
+6
-1
@@ -406,6 +406,8 @@ private suspend fun processMarmotWelcomeFlow(
|
||||
// A Welcome that already joined (or never can) is done. Replays of its wrap are routine:
|
||||
// every re-subscription re-delivers the last two days of gift wraps.
|
||||
if (manager.isTerminallyIngested(innerEvent.id)) return
|
||||
// Out of retries this session: a re-delivered wrap waits for the next app start.
|
||||
if (attempt == 0 && account.marmot.welcomeRetriesExhausted(innerEvent.id)) return
|
||||
|
||||
// "h" tag is optional per MIP-02 — some senders (e.g. whitenoise-rs) omit it.
|
||||
// nostrGroupId is derived from the MLS GroupContext's NostrGroupData extension instead.
|
||||
@@ -480,7 +482,10 @@ private fun scheduleWelcomeRetry(
|
||||
account: Account,
|
||||
attempt: Int,
|
||||
) {
|
||||
if (attempt >= WELCOME_RETRY_DELAYS_MS.size) return
|
||||
if (attempt >= WELCOME_RETRY_DELAYS_MS.size) {
|
||||
account.marmot.markWelcomeRetriesExhausted(welcome.id)
|
||||
return
|
||||
}
|
||||
if (!account.marmot.claimWelcomeRetry(welcome.id)) return
|
||||
account.scope.launch(Dispatchers.IO) {
|
||||
delay(WELCOME_RETRY_DELAYS_MS[attempt])
|
||||
|
||||
Reference in New Issue
Block a user