Polling backoff timers for active convos
This commit is contained in:
@@ -15,6 +15,8 @@ import {isNative} from '#/platform/detection'
|
|||||||
import {
|
import {
|
||||||
ACTIVE_POLL_INTERVAL,
|
ACTIVE_POLL_INTERVAL,
|
||||||
BACKGROUND_POLL_INTERVAL,
|
BACKGROUND_POLL_INTERVAL,
|
||||||
|
EXPIRED_TIMEOUT,
|
||||||
|
INACTIVE_POLL_INTERVAL,
|
||||||
INACTIVE_TIMEOUT,
|
INACTIVE_TIMEOUT,
|
||||||
NETWORK_FAILURE_STATUSES,
|
NETWORK_FAILURE_STATUSES,
|
||||||
} from '#/state/messages/convo/const'
|
} from '#/state/messages/convo/const'
|
||||||
@@ -102,6 +104,8 @@ export class Convo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private commit() {
|
private commit() {
|
||||||
|
this.refreshInactiveTimeout()
|
||||||
|
this.updateLastActiveTimestamp()
|
||||||
this.snapshot = undefined
|
this.snapshot = undefined
|
||||||
this.subscribers.forEach(subscriber => subscriber())
|
this.subscribers.forEach(subscriber => subscriber())
|
||||||
}
|
}
|
||||||
@@ -381,7 +385,6 @@ export class Convo {
|
|||||||
logger.DebugContext.convo,
|
logger.DebugContext.convo,
|
||||||
)
|
)
|
||||||
|
|
||||||
this.updateLastActiveTimestamp()
|
|
||||||
this.commit()
|
this.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +489,38 @@ export class Convo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on any state transition, like when the chat is backgrounded. This
|
* In `Ready` status, marks the chat as inactive and reduces polling.
|
||||||
|
*/
|
||||||
|
private inactiveTimeout: NodeJS.Timeout | undefined
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on every commit. If we're in ready state, it ensures we continue
|
||||||
|
* active polling, and sets up a timeout to back-off polling after a period
|
||||||
|
* of inactivity.
|
||||||
|
*/
|
||||||
|
private refreshInactiveTimeout() {
|
||||||
|
// clears either primary or secondary timeout
|
||||||
|
if (this.inactiveTimeout) {
|
||||||
|
clearTimeout(this.inactiveTimeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.status === ConvoStatus.Ready) {
|
||||||
|
this.requestPollInterval(ACTIVE_POLL_INTERVAL)
|
||||||
|
|
||||||
|
// initial timeout, move to inactive
|
||||||
|
this.inactiveTimeout = setTimeout(() => {
|
||||||
|
this.requestPollInterval(INACTIVE_POLL_INTERVAL)
|
||||||
|
|
||||||
|
// secondary timeout, move to background
|
||||||
|
this.inactiveTimeout = setTimeout(() => {
|
||||||
|
this.requestPollInterval(BACKGROUND_POLL_INTERVAL)
|
||||||
|
}, INACTIVE_TIMEOUT)
|
||||||
|
}, INACTIVE_TIMEOUT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on any commit, like when the chat is backgrounded. This
|
||||||
* value is then checked on background -> foreground transitions.
|
* value is then checked on background -> foreground transitions.
|
||||||
*/
|
*/
|
||||||
private updateLastActiveTimestamp() {
|
private updateLastActiveTimestamp() {
|
||||||
@@ -494,7 +528,7 @@ export class Convo {
|
|||||||
}
|
}
|
||||||
private wasChatInactive() {
|
private wasChatInactive() {
|
||||||
if (!this.lastActiveTimestamp) return true
|
if (!this.lastActiveTimestamp) return true
|
||||||
return Date.now() - this.lastActiveTimestamp > INACTIVE_TIMEOUT
|
return Date.now() - this.lastActiveTimestamp > EXPIRED_TIMEOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
private requestedPollInterval: (() => void) | undefined
|
private requestedPollInterval: (() => void) | undefined
|
||||||
|
|||||||
@@ -1,7 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Interval for when the user is actively using the chat.
|
||||||
|
*/
|
||||||
export const ACTIVE_POLL_INTERVAL = 1e3
|
export const ACTIVE_POLL_INTERVAL = 1e3
|
||||||
export const BACKGROUND_POLL_INTERVAL = 5e3
|
|
||||||
export const INACTIVE_TIMEOUT = 60e3 * 5
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interval for when the user is not actively using the chat, but could still
|
||||||
|
* be on the screen.
|
||||||
|
*/
|
||||||
|
export const INACTIVE_POLL_INTERVAL = 5e3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interval for when the chat is not visible to the user, or the user has not
|
||||||
|
* interacted with the chat in some time.
|
||||||
|
*/
|
||||||
|
export const BACKGROUND_POLL_INTERVAL = 20e3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout after which we consider the chat to be inactive, and we can slow
|
||||||
|
* polling.
|
||||||
|
*/
|
||||||
|
export const INACTIVE_TIMEOUT = 60e3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout after which we consider the chat stale and in need of a full reset.
|
||||||
|
*/
|
||||||
|
export const EXPIRED_TIMEOUT = 60e3 * 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retryable error statuses
|
||||||
|
*/
|
||||||
export const NETWORK_FAILURE_STATUSES = [
|
export const NETWORK_FAILURE_STATUSES = [
|
||||||
1, 408, 425, 429, 500, 502, 503, 504, 522, 524,
|
1, 408, 425, 429, 500, 502, 503, 504, 522, 524,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -322,15 +322,15 @@ export class MessagesEventBus {
|
|||||||
|
|
||||||
this.isPolling = true
|
this.isPolling = true
|
||||||
|
|
||||||
// logger.debug(
|
logger.debug(
|
||||||
// `${LOGGER_CONTEXT}: poll`,
|
`${LOGGER_CONTEXT}: poll`,
|
||||||
// {
|
{
|
||||||
// requestedPollIntervals: Array.from(
|
requestedPollIntervals: Array.from(
|
||||||
// this.requestedPollIntervals.values(),
|
this.requestedPollIntervals.values(),
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// logger.DebugContext.convo,
|
logger.DebugContext.convo,
|
||||||
// )
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await networkRetry(2, () => {
|
const response = await networkRetry(2, () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user