[PM-15444] Increase WASM timeout to 10s (#12158)

* Increase WASM timeout to 10s

* Change time to 3s, add logService with debug log
This commit is contained in:
Oscar Hinton 2024-11-28 11:58:09 +01:00 committed by GitHub
parent d4395d841d
commit 59686346d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 7 deletions

View File

@ -725,7 +725,7 @@ export default class MainBackground {
); );
const sdkClientFactory = flagEnabled("sdk") const sdkClientFactory = flagEnabled("sdk")
? new BrowserSdkClientFactory() ? new BrowserSdkClientFactory(this.logService)
: new NoopSdkClientFactory(); : new NoopSdkClientFactory();
this.sdkService = new DefaultSdkService( this.sdkService = new DefaultSdkService(
sdkClientFactory, sdkClientFactory,

View File

@ -1,4 +1,6 @@
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory"; import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { RecoverableSDKError } from "@bitwarden/common/platform/services/sdk/default-sdk.service";
import type { BitwardenClient } from "@bitwarden/sdk-internal"; import type { BitwardenClient } from "@bitwarden/sdk-internal";
import { BrowserApi } from "../../browser/browser-api"; import { BrowserApi } from "../../browser/browser-api";
@ -62,24 +64,39 @@ async function load() {
* Works both in popup and service worker. * Works both in popup and service worker.
*/ */
export class BrowserSdkClientFactory implements SdkClientFactory { export class BrowserSdkClientFactory implements SdkClientFactory {
constructor(private logService: LogService) {}
async createSdkClient( async createSdkClient(
...args: ConstructorParameters<typeof BitwardenClient> ...args: ConstructorParameters<typeof BitwardenClient>
): Promise<BitwardenClient> { ): Promise<BitwardenClient> {
const startTime = performance.now();
try { try {
await loadWithTimeout(); await loadWithTimeout();
} catch (error) { } catch (error) {
throw new Error(`Failed to load: ${error.message}`); throw new Error(`Failed to load: ${error.message}`);
} }
return Promise.resolve((globalThis as any).init_sdk(...args)); const endTime = performance.now();
const elapsed = Math.round((endTime - startTime) / 1000);
const instance = (globalThis as any).init_sdk(...args);
this.logService.info("WASM SDK loaded in", Math.round(endTime - startTime), "ms");
// If it takes 3 seconds or more to load, we want to capture it.
if (elapsed >= 3) {
throw new RecoverableSDKError(instance, elapsed);
}
return instance;
} }
} }
const loadWithTimeout = async () => { const loadWithTimeout = async () => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
const timer = setTimeout(() => { const timer = setTimeout(() => {
reject(new Error("Operation timed out after 1 second")); reject(new Error("Operation timed out after 10 second"));
}, 1000); }, 10000);
load() load()
.then(() => { .then(() => {

View File

@ -576,8 +576,9 @@ const safeProviders: SafeProvider[] = [
}), }),
safeProvider({ safeProvider({
provide: SdkClientFactory, provide: SdkClientFactory,
useClass: flagEnabled("sdk") ? BrowserSdkClientFactory : NoopSdkClientFactory, useFactory: (logService) =>
deps: [], flagEnabled("sdk") ? new BrowserSdkClientFactory(logService) : new NoopSdkClientFactory(),
deps: [LogService],
}), }),
safeProvider({ safeProvider({
provide: LoginEmailService, provide: LoginEmailService,

View File

@ -32,13 +32,33 @@ import { SdkService } from "../../abstractions/sdk/sdk.service";
import { compareValues } from "../../misc/compare-values"; import { compareValues } from "../../misc/compare-values";
import { EncryptedString } from "../../models/domain/enc-string"; import { EncryptedString } from "../../models/domain/enc-string";
export class RecoverableSDKError extends Error {
sdk: BitwardenClient;
timeout: number;
constructor(sdk: BitwardenClient, timeout: number) {
super(`SDK took ${timeout}s to initialize`);
this.sdk = sdk;
this.timeout = timeout;
}
}
export class DefaultSdkService implements SdkService { export class DefaultSdkService implements SdkService {
private sdkClientCache = new Map<UserId, Observable<BitwardenClient>>(); private sdkClientCache = new Map<UserId, Observable<BitwardenClient>>();
client$ = this.environmentService.environment$.pipe( client$ = this.environmentService.environment$.pipe(
concatMap(async (env) => { concatMap(async (env) => {
const settings = this.toSettings(env); const settings = this.toSettings(env);
try {
return await this.sdkClientFactory.createSdkClient(settings, LogLevel.Info); return await this.sdkClientFactory.createSdkClient(settings, LogLevel.Info);
} catch (e) {
if (e instanceof RecoverableSDKError) {
await this.failedToInitialize("sdk", e);
return e.sdk;
}
throw e;
}
}), }),
shareReplay({ refCount: true, bufferSize: 1 }), shareReplay({ refCount: true, bufferSize: 1 }),
); );