From d44c55b6afa31c5937474d9ec0ba70fe14deb9cc Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 4 Jun 2021 10:21:05 +1000 Subject: [PATCH] WIP --- js/background.js | 9 +++ ts/opengroup/opengroupV2/ApiAuth.ts | 66 +++++++++++++++---- ts/opengroup/opengroupV2/OpenGroupAPIV2.ts | 4 +- .../opengroupV2/OpenGroupAPIV2CompactPoll.ts | 2 + .../opengroupV2/OpenGroupManagerV2.ts | 30 +++++---- .../opengroupV2/OpenGroupServerPoller.ts | 13 ++-- ts/session/utils/Promise.ts | 3 + 7 files changed, 95 insertions(+), 32 deletions(-) diff --git a/js/background.js b/js/background.js index a35b84626..bfa337fc8 100644 --- a/js/background.js +++ b/js/background.js @@ -280,6 +280,15 @@ ); window.log.info('Cleanup: complete'); + const observer = new PerformanceObserver(list => { + console.warn('Long Task detected! 🚩️'); + const entries = list.getEntries(); + console.warn(entries); + // debugger; + }); + + observer.observe({ entryTypes: ['longtask'] }); + window.log.info('listening for registration events'); Whisper.events.on('registration_done', async () => { window.log.info('handling registration event'); diff --git a/ts/opengroup/opengroupV2/ApiAuth.ts b/ts/opengroup/opengroupV2/ApiAuth.ts index b19ab8027..10cd62ba2 100644 --- a/ts/opengroup/opengroupV2/ApiAuth.ts +++ b/ts/opengroup/opengroupV2/ApiAuth.ts @@ -1,4 +1,8 @@ -import { getV2OpenGroupRoomByRoomId, saveV2OpenGroupRoom } from '../../data/opengroups'; +import { + getV2OpenGroupRoomByRoomId, + OpenGroupV2Room, + saveV2OpenGroupRoom, +} from '../../data/opengroups'; import { allowOnlyOneAtATime } from '../../session/utils/Promise'; import { fromBase64ToArrayBuffer, toHex } from '../../session/utils/String'; import { getIdentityKeyPair, getOurPubKeyStrFromCache } from '../../session/utils/User'; @@ -31,30 +35,25 @@ async function claimAuthToken( return authToken; } -export async function getAuthToken({ +async function oneAtATimeGetAuth({ serverUrl, roomId, -}: OpenGroupRequestCommonType): Promise { - // first try to fetch from db a saved token. - const roomDetails = await getV2OpenGroupRoomByRoomId({ serverUrl, roomId }); - if (!roomDetails) { - window?.log?.warn('getAuthToken Room does not exist.'); - return null; - } - if (roomDetails?.token) { - return roomDetails.token; - } - - await allowOnlyOneAtATime(`getAuthToken${serverUrl}:${roomId}`, async () => { + roomDetails, +}: OpenGroupRequestCommonType & { roomDetails: OpenGroupV2Room }) { + return allowOnlyOneAtATime(`getAuthToken${serverUrl}:${roomId}`, async () => { try { window?.log?.info( `Triggering getAuthToken with serverUrl:'${serverUrl}'; roomId: '${roomId}'` ); const token = await requestNewAuthToken({ serverUrl, roomId }); + if (roomId === 'lokinet') { + debugger; + } if (!token) { window?.log?.warn('invalid new auth token', token); return; } + window?.log?.info(`Got AuthToken for serverUrl:'${serverUrl}'; roomId: '${roomId}'`); const claimedToken = await claimAuthToken(token, serverUrl, roomId); if (!claimedToken) { @@ -62,15 +61,44 @@ export async function getAuthToken({ } else { window?.log?.info(`Claimed AuthToken for serverUrl:'${serverUrl}'; roomId: '${roomId}'`); } + console.error('Saving token to claimed token for ', roomDetails.roomId); // still save it to the db. just to mark it as to be refreshed later + if (roomId === 'lokinet') { + debugger; + } roomDetails.token = claimedToken || ''; + if (roomId === 'lokinet') { + debugger; + } + await saveV2OpenGroupRoom(roomDetails); + window?.log?.info(`AuthToken saved to DB for serverUrl:'${serverUrl}'; roomId: '${roomId}'`); + return claimedToken; } catch (e) { window?.log?.error('Failed to getAuthToken', e); throw e; } }); +} + +export async function getAuthToken({ + serverUrl, + roomId, +}: OpenGroupRequestCommonType): Promise { + // first try to fetch from db a saved token. + const roomDetails = await getV2OpenGroupRoomByRoomId({ serverUrl, roomId }); + if (!roomDetails) { + window?.log?.warn('getAuthToken Room does not exist.'); + return null; + } + if (roomDetails?.token) { + console.error('Already having a saved token ', roomDetails.roomId); + + return roomDetails.token; + } + + const claimedToken = await oneAtATimeGetAuth({ roomDetails, roomId, serverUrl }); // fetch the data from the db again, which should have been written in the saveV2OpenGroupRoom() call above const refreshedRoomDetails = await getV2OpenGroupRoomByRoomId({ @@ -81,7 +109,17 @@ export async function getAuthToken({ window?.log?.warn('getAuthToken Room does not exist.'); return null; } + // if the claimedToken got overriden, save it again + if (!refreshedRoomDetails?.token && claimedToken) { + refreshedRoomDetails.token = claimedToken; + console.error('claimed auth token for overriden. Forcing writing it', roomDetails.roomId); + + await saveV2OpenGroupRoom(refreshedRoomDetails); + } + if (refreshedRoomDetails?.token) { + console.error('Returning freshclaimed token for ', roomDetails.roomId); + return refreshedRoomDetails?.token; } return null; diff --git a/ts/opengroup/opengroupV2/OpenGroupAPIV2.ts b/ts/opengroup/opengroupV2/OpenGroupAPIV2.ts index b4714d6c6..7928c790f 100644 --- a/ts/opengroup/opengroupV2/OpenGroupAPIV2.ts +++ b/ts/opengroup/opengroupV2/OpenGroupAPIV2.ts @@ -145,6 +145,7 @@ export async function sendApiV2Request( window?.log?.warn('Got 401, but this room does not exist'); return null; } + console.error('Overriding token to undefined for ', roomDetails.roomId) roomDetails.token = undefined; // we might need to retry doing the request here, but how to make sure we don't retry indefinetely? await saveV2OpenGroupRoom(roomDetails); @@ -343,7 +344,8 @@ export const getMemberCount = async ( const result = await exports.sendApiV2Request(request); if (parseStatusCodeFromOnionRequest(result) !== 200) { window?.log?.warn( - `getMemberCount failed invalid status code for serverUrl:'${roomInfos.serverUrl}' roomId:'${roomInfos.roomId}'` + `getMemberCount failed invalid status code for serverUrl:'${roomInfos.serverUrl}' roomId:'${roomInfos.roomId}; '`, + result ); return; } diff --git a/ts/opengroup/opengroupV2/OpenGroupAPIV2CompactPoll.ts b/ts/opengroup/opengroupV2/OpenGroupAPIV2CompactPoll.ts index a7342b2e2..280941c79 100644 --- a/ts/opengroup/opengroupV2/OpenGroupAPIV2CompactPoll.ts +++ b/ts/opengroup/opengroupV2/OpenGroupAPIV2CompactPoll.ts @@ -272,6 +272,7 @@ async function sendOpenGroupV2RequestCompactPoll( const roomPollValidResults = results.filter(ret => ret.statusCode === 200); if (roomWithTokensToRefresh) { + window.log.info('We got those rooms to refresh the token ', roomWithTokensToRefresh); await Promise.all( roomWithTokensToRefresh.map(async roomId => { const roomDetails = await getV2OpenGroupRoomByRoomId({ @@ -281,6 +282,7 @@ async function sendOpenGroupV2RequestCompactPoll( if (!roomDetails) { return; } + console.error('Overriding token to undefined for ', roomDetails.roomId); roomDetails.token = undefined; // we might need to retry doing the request here, but how to make sure we don't retry indefinetely? await saveV2OpenGroupRoom(roomDetails); diff --git a/ts/opengroup/opengroupV2/OpenGroupManagerV2.ts b/ts/opengroup/opengroupV2/OpenGroupManagerV2.ts index 1af820153..f3f247067 100644 --- a/ts/opengroup/opengroupV2/OpenGroupManagerV2.ts +++ b/ts/opengroup/opengroupV2/OpenGroupManagerV2.ts @@ -15,6 +15,7 @@ import { OpenGroupServerPoller } from './OpenGroupServerPoller'; import _ from 'lodash'; import { deleteAuthToken } from './ApiAuth'; +import autoBind from 'auto-bind'; export class OpenGroupManagerV2 { public static readonly useV2OpenGroups = false; @@ -29,8 +30,7 @@ export class OpenGroupManagerV2 { private isPolling = false; private constructor() { - this.startPollingBouncy = this.startPollingBouncy.bind(this); - this.attemptConnectionV2 = this.attemptConnectionV2.bind(this); + autoBind(this); } public static getInstance() { @@ -79,14 +79,20 @@ export class OpenGroupManagerV2 { this.isPolling = false; } - public addRoomToPolledRooms(roomInfos: OpenGroupRequestCommonType) { - const poller = this.pollers.get(roomInfos.serverUrl); - if (!poller) { - this.pollers.set(roomInfos.serverUrl, new OpenGroupServerPoller([roomInfos])); - return; + public addRoomToPolledRooms(roomInfos: Array) { + const grouped = _.groupBy(roomInfos, r => r.serverUrl); + const groupedArray = Object.values(grouped); + + for (const groupedRooms of groupedArray) { + const groupedRoomsServerUrl = groupedRooms[0].serverUrl; + const poller = this.pollers.get(groupedRoomsServerUrl); + if (!poller) { + this.pollers.set(groupedRoomsServerUrl, new OpenGroupServerPoller(groupedRooms)); + } else { + // this won't do a thing if the room is already polled for + roomInfos.forEach(poller.addRoomToPoll); + } } - // this won't do a thing if the room is already polled for - poller.addRoomToPoll(roomInfos); } public removeRoomFromPolledRooms(roomInfos: OpenGroupRequestCommonType) { @@ -138,9 +144,7 @@ export class OpenGroupManagerV2 { // refresh our roomInfos list allRoomInfos = await getAllV2OpenGroupRooms(); if (allRoomInfos) { - allRoomInfos.forEach(infos => { - this.addRoomToPolledRooms(infos); - }); + this.addRoomToPolledRooms([...allRoomInfos.values()]); } this.isPolling = true; @@ -197,7 +201,7 @@ export class OpenGroupManagerV2 { await conversation.commit(); // start polling this room - this.addRoomToPolledRooms(room); + this.addRoomToPolledRooms([room]); return conversation; } catch (e) { diff --git a/ts/opengroup/opengroupV2/OpenGroupServerPoller.ts b/ts/opengroup/opengroupV2/OpenGroupServerPoller.ts index 9c2367e75..087814408 100644 --- a/ts/opengroup/opengroupV2/OpenGroupServerPoller.ts +++ b/ts/opengroup/opengroupV2/OpenGroupServerPoller.ts @@ -23,9 +23,9 @@ import { fromBase64ToArrayBuffer } from '../../session/utils/String'; import { getAuthToken } from './ApiAuth'; import { DURATION } from '../../session/constants'; -const pollForEverythingInterval = DURATION.SECONDS * 4; +const pollForEverythingInterval = DURATION.SECONDS * 10; const pollForRoomAvatarInterval = DURATION.DAYS * 1; -const pollForMemberCountInterval = DURATION.MINUTES * 10; +const pollForMemberCountInterval = DURATION.MINUTES * 30; /** * An OpenGroupServerPollerV2 polls for everything for a particular server. We should @@ -124,7 +124,7 @@ export class OpenGroupServerPoller { this.roomIdsToPoll.add(room.roomId); // if we are not already polling right now, trigger a polling - void this.triggerPollAfterAdd(); + void this.triggerPollAfterAdd(room); } public removeRoomFromPoll(room: OpenGroupRequestCommonType) { @@ -173,7 +173,12 @@ export class OpenGroupServerPoller { } private async triggerPollAfterAdd(room?: OpenGroupRequestCommonType) { - if (this.roomIdsToPoll.size) { + if (room) { + // this call either get the token from db, or fetch a new one + console.warn('getAuthToken with triggerPollAfterAdd with room', room.roomId); + await getAuthToken({ roomId: room.roomId, serverUrl: this.serverUrl }); + } else if (this.roomIdsToPoll.size) { + console.warn('getAuthToken with triggerPollAfterAdd with all rooms'); await Promise.all( [...this.roomIdsToPoll].map(async r => { // this call either get the token from db, or fetch a new one diff --git a/ts/session/utils/Promise.ts b/ts/session/utils/Promise.ts index 1642ceda6..891dc2b96 100644 --- a/ts/session/utils/Promise.ts +++ b/ts/session/utils/Promise.ts @@ -25,6 +25,7 @@ export async function allowOnlyOneAtATime( ) { // if currently not in progress if (snodeGlobalLocks[name] === undefined) { + console.warn(`${name} not already running, creating it`); // set lock snodeGlobalLocks[name] = new Promise(async (resolve, reject) => { // set up timeout feature @@ -71,6 +72,8 @@ export async function allowOnlyOneAtATime( // release the kraken resolve(innerRetVal); }); + } else { + console.warn(`${name} already running, returning it`); } return snodeGlobalLocks[name]; }