Android #618 offline-mode UX + Sonos polish + server DRY #81

Merged
bvandeusen merged 7 commits from dev into main 2026-06-04 12:53:59 -04:00
Showing only changes of commit 4d0a0b8e09 - Show all commits
@@ -19,6 +19,7 @@ import com.fabledsword.minstrel.player.output.upnp.UpnpDiscoveryController
import com.fabledsword.minstrel.player.output.upnp.bareUdn import com.fabledsword.minstrel.player.output.upnp.bareUdn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -372,6 +373,13 @@ class OutputPickerController @Inject constructor(
if (outcome.isSuccess) { if (outcome.isSuccess) {
consecutiveFailures = 0 consecutiveFailures = 0
succeeded += 1 succeeded += 1
// Throttle the burst so we don't tickle Sonos's burst-add
// rejection -- logcat 2026-06-04 showed 33 consecutive
// failures clustered at ~10ms intervals once offset 39 was
// reached, which looks like a rate-limit kicking in. The
// delay is small enough that extending 100 tracks adds
// only ~5s to background work that's already async.
delay(EXTEND_THROTTLE_MS)
} else { } else {
consecutiveFailures += 1 consecutiveFailures += 1
val e = outcome.exceptionOrNull() val e = outcome.exceptionOrNull()
@@ -423,5 +431,6 @@ class OutputPickerController @Inject constructor(
private companion object { private companion object {
const val EXTEND_ABORT_AFTER_FAILURES = 3 const val EXTEND_ABORT_AFTER_FAILURES = 3
const val EXTEND_THROTTLE_MS = 50L
} }
} }