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 { postJSON } from '../../infrastructure/fetch-json'
import isSplitTestEnabled from '../../utils/isSplitTestEnabled' import isSplitTestEnabled from '../../utils/isSplitTestEnabled'
const MAX_CHECKS_PER_PAGE_LOAD = 3
const INITIAL_DELAY_MS = 30_000 const INITIAL_DELAY_MS = 30_000
const DELAY_BETWEEN_PROBES_MS = 1_000 const DELAY_BETWEEN_PROBES_MS = 1_000
const TIMEOUT_MS = 30_000 const TIMEOUT_MS = 30_000
@ -180,12 +181,18 @@ export async function checkUserContentDomainAccess() {
} }
let failed = 0 let failed = 0
const epochBeforeCheck = networkEpoch
for (const { url, init, estimatedSize, hash, chunks } of cases) { for (const { url, init, estimatedSize, hash, chunks } of cases) {
await sleep(DELAY_BETWEEN_PROBES_MS) await sleep(DELAY_BETWEEN_PROBES_MS)
try { try {
await singleCheck(url, init, estimatedSize, hash, chunks) await singleCheck(url, init, estimatedSize, hash, chunks)
} catch (err: any) { } 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++ failed++
OError.tag(err, 'user-content-domain-access-check failed', { OError.tag(err, 'user-content-domain-access-check failed', {
url, url,
@ -214,8 +221,45 @@ export function userContentDomainAccessCheckPassed() {
return accessCheckPassed 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() { 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() checkUserContentDomainAccess()
.then(ok => { .then(ok => {
accessCheckPassed = ok accessCheckPassed = ok
@ -223,5 +267,5 @@ export function scheduleUserContentDomainAccessCheck() {
.catch(err => { .catch(err => {
captureException(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() cleanupServiceWorker()
if (isSplitTestEnabled('user-content-domain-access-check')) { scheduleUserContentDomainAccessCheck()
scheduleUserContentDomainAccessCheck()
}
angular.module('SharelatexApp').config(function ($provide) { angular.module('SharelatexApp').config(function ($provide) {
$provide.decorator('$browser', [ $provide.decorator('$browser', [