Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ package io.getstream.video.android.core.ringing
* must be usable, and a non-positive one is rejected rather than quietly disabling the fallback.
*
* @param startAfterMs how long a ring must go without a participant's ring status changing before
* polling begins. Kept well above the coordinator's websocket ping interval so a merely slow
* answer does not poll.
* polling begins. This is the trade the whole fallback turns on: a shorter quiet period recovers a
* dropped outcome sooner, and also makes rings whose callee is merely slow to answer pay for a read
* they did not need. The default is tuned for the first, because a caller stuck on a ringing screen
* is a visible failure and an extra read is not.
* @param intervalMs the gap between reads once polling has begun. Measured from the end of one
* read to the start of the next, so a slow read widens the gap rather than being absorbed by it.
*/
Expand All @@ -40,7 +42,7 @@ public data class RingStatePollingConfig(
}

public companion object {
public const val DEFAULT_START_AFTER_MS: Long = 15_000
public const val DEFAULT_START_AFTER_MS: Long = 9_000
public const val DEFAULT_INTERVAL_MS: Long = 5_000

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class RingStatePollerTest {
})

poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(14_999)
advanceTimeBy(8_999)

assertThat(reads).isEqualTo(0)
poller.stop()
Expand All @@ -82,7 +82,7 @@ class RingStatePollerTest {
})

poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(15_001)
advanceTimeBy(9_001)
assertThat(reads).isEqualTo(1)

advanceTimeBy(5_000)
Expand All @@ -100,15 +100,15 @@ class RingStatePollerTest {
})

poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(10_000)
advanceTimeBy(5_000)

// A rejection from one callee does not settle a group ring, so the poller stays armed —
// but the socket just proved it is alive, so the wait starts over.
poller.onRingParticipantStatusUpdate()
advanceTimeBy(10_000)
advanceTimeBy(5_000)
assertThat(reads).isEqualTo(0)

advanceTimeBy(5_001)
advanceTimeBy(4_001)
assertThat(reads).isEqualTo(1)

poller.stop()
Expand All @@ -125,9 +125,9 @@ class RingStatePollerTest {
poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(60_000)

// 15s quiet period, then reads at 20/25/30s — the read that would land past the
// 9s quiet period, then reads at 9/14/19/24/29s — the read that would land past the
// deadline is not issued.
assertThat(reads).isEqualTo(3)
assertThat(reads).isEqualTo(5)
poller.stop()
}

Expand All @@ -144,7 +144,7 @@ class RingStatePollerTest {
poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(25_001)

assertThat(reads).isEqualTo(3)
assertThat(reads).isEqualTo(4)
poller.stop()
}

Expand All @@ -157,7 +157,7 @@ class RingStatePollerTest {
})

poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(15_001)
advanceTimeBy(9_001)
assertThat(reads).isEqualTo(1)

poller.stop()
Expand Down Expand Up @@ -207,8 +207,8 @@ class RingStatePollerTest {
poller.start({ sessionId }, { 600_000L })
advanceTimeBy(600_000)

// 60s ceiling: quiet period to 15s, then reads at 20..55s.
assertThat(reads).isEqualTo(9)
// 60s ceiling: quiet period to 9s, then reads at 9..59s.
assertThat(reads).isEqualTo(11)
poller.stop()
}

Expand All @@ -228,8 +228,8 @@ class RingStatePollerTest {
poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(600_000)

// 30s window: quiet period to 15s, then reads at 15, 20 and 25s, and no further.
assertThat(reads).isEqualTo(3)
// 30s window: quiet period to 9s, then reads at 9, 14, 19, 24 and 29s, and no further.
assertThat(reads).isEqualTo(5)
poller.stop()
}

Expand All @@ -256,7 +256,7 @@ class RingStatePollerTest {
advanceTimeBy(600_000)

// The reads of one loop over a 30s window, not two loops interleaved.
assertThat(reads).isEqualTo(3)
assertThat(reads).isEqualTo(5)
poller.stop()
}

Expand All @@ -272,7 +272,7 @@ class RingStatePollerTest {
poller.start({ sessionId }, { 0L })
advanceTimeBy(600_000)

assertThat(reads).isEqualTo(3)
assertThat(reads).isEqualTo(5)
poller.stop()
}

Expand All @@ -287,8 +287,8 @@ class RingStatePollerTest {
poller.start({ sessionId }, { null })
advanceTimeBy(600_000)

// 30s default, not the 60s ceiling: quiet period to 15s, then reads at 15, 20 and 25s.
assertThat(reads).isEqualTo(3)
// 30s default, not the 60s ceiling: quiet period to 9s, then reads at 9 through 29s.
assertThat(reads).isEqualTo(5)
poller.stop()
}

Expand Down Expand Up @@ -325,8 +325,8 @@ class RingStatePollerTest {
},
)

// A longer window than the default: this exercises three polls, which does not fit in one
// 30s ring.
// A longer window than the default, so the reads this walks through are not also being
// bounded by the ring deadline.
poller.start({ current }, { 60_000L })
advanceTimeBy(20_001)
assertThat(seen).isEmpty()
Expand All @@ -350,7 +350,7 @@ class RingStatePollerTest {
poller.start({ sessionId }, { ringTimeout })
advanceTimeBy(20_001)

assertThat(seen).hasSize(2)
assertThat(seen).hasSize(3)
assertThat(seen.first().sessionId).isEqualTo(sessionId)
poller.stop()
}
Expand Down
Loading