Merge pull request #11443 from overleaf/jpa-handle-connection-change

[web] user-content-domain-access-check: handle connection changes

GitOrigin-RevId: 7858b9e33741fc515dfa96aeba8d0942ce2911a5
This commit is contained in:
Jakob Ackermann 2023-01-30 09:53:34 +00:00 committed by Copybot
parent 781c1c97c7
commit 4eadd92598
2 changed files with 47 additions and 5 deletions

View file

@ -10,6 +10,7 @@ import { captureException } from '../../infrastructure/error-reporter'
import { postJSON } from '../../infrastructure/fetch-json'
import isSplitTestEnabled from '../../utils/isSplitTestEnabled'
const MAX_CHECKS_PER_PAGE_LOAD = 3
const INITIAL_DELAY_MS = 30_000
const DELAY_BETWEEN_PROBES_MS = 1_000
const TIMEOUT_MS = 30_000
@ -180,12 +181,18 @@ export async function checkUserContentDomainAccess() {
}
let failed = 0
const epochBeforeCheck = networkEpoch
for (const { url, init, estimatedSize, hash, chunks } of cases) {
await sleep(DELAY_BETWEEN_PROBES_MS)
try {
await singleCheck(url, init, estimatedSize, hash, chunks)
} catch (err: any) {
if (!navigator.onLine || epochBeforeCheck !== networkEpoch) {
// It is very likely that the request failed because we are offline or
// the network connection changed just now.
return false
}
failed++
OError.tag(err, 'user-content-domain-access-check failed', {
url,
@ -214,8 +221,45 @@ export function userContentDomainAccessCheckPassed() {
return accessCheckPassed
}
let networkEpoch = performance.now()
window.addEventListener('offline', () => {
// We are offline. Abort any scheduled check.
clearTimeout(lastScheduledCheck)
accessCheckPassed = false
networkEpoch = performance.now()
})
window.addEventListener('online', () => {
// We are online again. Schedule another check for this network.
accessCheckPassed = false
networkEpoch = performance.now()
scheduleUserContentDomainAccessCheck()
})
try {
// Note: navigator.connection is not available on Firefox and Safari.
// Docs: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
navigator.connection.addEventListener('change', () => {
// The network changed. Schedule another check for it.
accessCheckPassed = false
networkEpoch = performance.now()
scheduleUserContentDomainAccessCheck()
})
} catch (e) {}
let lastScheduledCheck: number
let remainingChecks = MAX_CHECKS_PER_PAGE_LOAD
export function scheduleUserContentDomainAccessCheck() {
sleep(INITIAL_DELAY_MS).then(() => {
if (!isSplitTestEnabled('user-content-domain-access-check')) return
clearTimeout(lastScheduledCheck)
const networkEpochBeforeDelay = networkEpoch
lastScheduledCheck = window.setTimeout(() => {
if (!window.navigator.onLine || networkEpochBeforeDelay !== networkEpoch) {
// Must be online for more than INITIAL_DELAY_MS before we check.
// We want to avoid false-positives from flaky network connections.
// Try again in INITIAL_DELAY_MS.
return scheduleUserContentDomainAccessCheck()
}
if (accessCheckPassed) return
if (remainingChecks-- <= 0) return
checkUserContentDomainAccess()
.then(ok => {
accessCheckPassed = ok
@ -223,5 +267,5 @@ export function scheduleUserContentDomainAccessCheck() {
.catch(err => {
captureException(err)
})
})
}, INITIAL_DELAY_MS)
}

View file

@ -481,9 +481,7 @@ If the project has been renamed please look in your project list for a new proje
)
cleanupServiceWorker()
if (isSplitTestEnabled('user-content-domain-access-check')) {
scheduleUserContentDomainAccessCheck()
}
angular.module('SharelatexApp').config(function ($provide) {
$provide.decorator('$browser', [