Skip to content

Commit

Permalink
Wait for Chelonia, more error logs (#2471)
Browse files Browse the repository at this point in the history
* Wait for Chelonia, more error logs

* Handle failed sync for login

* Reduce SW timeout to 8s
  • Loading branch information
corrideat authored Dec 18, 2024
1 parent 46a31f6 commit 6b1ad58
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
29 changes: 29 additions & 0 deletions frontend/controller/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,34 @@ sbp('sbp/selectors/register', {
await swRegistration.update()
setInterval(() => sbp('service-worker/update'), HOURS_MILLIS)

// Send a 'ready' message to the SW and wait back for a response
// This way we ensure that Chelonia has been set up
await new Promise((resolve, reject) => {
const messageChannel = new MessageChannel()
messageChannel.port1.onmessage = (event) => {
if (event.data.type === 'ready') {
resolve()
} else {
reject(event.data.error)
}
messageChannel.port1.close()
}
messageChannel.port1.onmessageerror = () => {
reject(new Error('Message error'))
messageChannel.port1.close()
}

navigator.serviceWorker.ready.then((worker) => {
worker.active.postMessage({
type: 'ready',
port: messageChannel.port2
}, [messageChannel.port2])
}).catch((e) => {
reject(e)
messageChannel.port1.close()
})
})

// Keep the service worker alive while the window is open
// The default idle timeout on Chrome and Firefox is 30 seconds. We send
// a ping message every 5 seconds to ensure that the worker remains
Expand Down Expand Up @@ -92,6 +120,7 @@ sbp('sbp/selectors/register', {
})
} catch (e) {
console.error('error setting up service worker:', e)
throw e
}
},
// We call this when the notification permission changes, to create a push
Expand Down
4 changes: 2 additions & 2 deletions frontend/controller/serviceworkers/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default (sbp('sbp/selectors/register', {
const pubsub = sbp('okTurtles.data/get', PUBSUB_INSTANCE)
if (!pubsub) reject(new Error('Missing pubsub instance'))

const readyState = pubsub.socket.readyState
const readyState = pubsub.socket?.readyState
if (readyState !== WebSocket.OPEN) {
reject(new Error('WebSocket connection is not open'))
}
Expand Down Expand Up @@ -71,7 +71,7 @@ export default (sbp('sbp/selectors/register', {
const pubsub = sbp('okTurtles.data/get', PUBSUB_INSTANCE)
if (!pubsub) throw new Error('Missing pubsub instance')

const readyState = pubsub.socket.readyState
const readyState = pubsub.socket?.readyState
if (readyState !== WebSocket.OPEN) {
throw new Error('WebSocket connection is not open')
}
Expand Down
20 changes: 20 additions & 0 deletions frontend/controller/serviceworkers/sw-primary.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,26 @@ self.addEventListener('message', function (event) {
case 'event':
sbp('okTurtles.events/emit', event.data.subtype, ...deserializer(event.data.data))
break
case 'ready': {
// The 'ready' message is sent by a client (i.e., a tab or window) to
// ensure that Chelonia has been setup
const port = event.data.port
Promise.race([
setupChelonia(),
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Timed out setting up Chelonia'))
}, 30e3)
})
]).then(() => {
port.postMessage({ type: 'ready' })
}, (e) => {
port.postMessage({ type: 'error', error: e })
}).finally(() => {
port.close()
})
break
}
default:
console.error('[sw] unknown message type:', event.data)
break
Expand Down
2 changes: 1 addition & 1 deletion frontend/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ async function startApp () {
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Timed out setting up service worker'))
}, 16e3)
}, 8e3)
})]
).catch(e => {
console.error('[main] Error setting up service worker', e)
Expand Down
10 changes: 7 additions & 3 deletions frontend/setupChelonia.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,12 @@ const setupChelonia = async (): Promise<*> => {
if (cheloniaState.loggedIn?.identityContractID !== identityContractID) return
// it is important we first login before syncing any contracts here since that will load the
// state and the contract sideEffects will sometimes need that state, e.g. loggedIn.identityContractID
await sbp('chelonia/contract/sync', identityContractID)
const contractIDs = groupContractsByType(cheloniaState.contracts)
await syncContractsInOrder(contractIDs)
await sbp('chelonia/contract/sync', identityContractID).then(async () => {
const contractIDs = groupContractsByType(cheloniaState.contracts)
await syncContractsInOrder(contractIDs)
}).catch(e => {
console.error('[setupChelonia] Error syncing identity contract and groups', e)
})
})
}

Expand All @@ -310,6 +313,7 @@ export default ((() => {
return () => {
if (!promise) {
promise = setupChelonia().catch((e) => {
console.error('[setupChelonia] Error during chelonia setup', e)
promise = undefined // Reset on error
throw e // Re-throw the error
})
Expand Down

0 comments on commit 6b1ad58

Please sign in to comment.