fix: Enable async loading of all dependency resources (#408)

* Async loading

* Fix lint
This commit is contained in:
Akim 2023-12-29 03:33:28 +07:00 committed by GitHub
parent 1e42e58a83
commit f5425b4746
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 54 deletions

View File

@ -14,7 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { Worker } from "@fluencelabs/threads/master"; import type { MarineBackgroundInterface } from "@fluencelabs/marine-worker";
import { ModuleThread } from "@fluencelabs/threads/master";
import versions from "./versions.js"; import versions from "./versions.js";
@ -23,7 +24,7 @@ type VersionedPackage = { name: string; version: string };
export type GetWorkerFn = ( export type GetWorkerFn = (
pkg: FetchedPackages, pkg: FetchedPackages,
CDNUrl: string, CDNUrl: string,
) => Promise<Worker>; ) => Promise<ModuleThread<MarineBackgroundInterface>>;
export const getVersionedPackage = (pkg: FetchedPackages): VersionedPackage => { export const getVersionedPackage = (pkg: FetchedPackages): VersionedPackage => {
return { return {

View File

@ -14,7 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { BlobWorker } from "@fluencelabs/threads/master"; import type { MarineBackgroundInterface } from "@fluencelabs/marine-worker";
import { BlobWorker, ModuleThread, spawn } from "@fluencelabs/threads/master";
import { fetchResource } from "../fetchers/browser.js"; import { fetchResource } from "../fetchers/browser.js";
import type { FetchedPackages, GetWorkerFn } from "../types.js"; import type { FetchedPackages, GetWorkerFn } from "../types.js";
@ -34,5 +35,9 @@ export const getWorker: GetWorkerFn = async (
}; };
const workerCode = await fetchWorkerCode(); const workerCode = await fetchWorkerCode();
return BlobWorker.fromText(workerCode);
const workerThread: ModuleThread<MarineBackgroundInterface> =
await spawn<MarineBackgroundInterface>(BlobWorker.fromText(workerCode));
return workerThread;
}; };

View File

@ -18,12 +18,13 @@ import { createRequire } from "module";
import { dirname, relative } from "path"; import { dirname, relative } from "path";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
import { Worker } from "@fluencelabs/threads/master"; import type { MarineBackgroundInterface } from "@fluencelabs/marine-worker";
import { ModuleThread, spawn, Worker } from "@fluencelabs/threads/master";
import type { FetchedPackages, GetWorkerFn } from "../types.js"; import type { FetchedPackages, GetWorkerFn } from "../types.js";
import { getVersionedPackage } from "../types.js"; import { getVersionedPackage } from "../types.js";
export const getWorker: GetWorkerFn = (pkg: FetchedPackages) => { export const getWorker: GetWorkerFn = async (pkg: FetchedPackages) => {
const require = createRequire(import.meta.url); const require = createRequire(import.meta.url);
const pathToThisFile = dirname(fileURLToPath(import.meta.url)); const pathToThisFile = dirname(fileURLToPath(import.meta.url));
@ -33,5 +34,8 @@ export const getWorker: GetWorkerFn = (pkg: FetchedPackages) => {
const relativePathToWorker = relative(pathToThisFile, pathToWorker); const relativePathToWorker = relative(pathToThisFile, pathToWorker);
return Promise.resolve(new Worker(relativePathToWorker)); const workerThread: ModuleThread<MarineBackgroundInterface> =
await spawn<MarineBackgroundInterface>(new Worker(relativePathToWorker));
return workerThread;
}; };

View File

@ -356,9 +356,8 @@ export abstract class FluencePeer {
await this.connection.sendParticle(item.result.nextPeerPks, newParticle); await this.connection.sendParticle(item.result.nextPeerPks, newParticle);
log_particle.trace("id %s. send successful", newParticle.id); log_particle.trace("id %s. send successful", newParticle.id);
} catch (e) { } catch (e) {
log_particle.error("id %s. send failed %j", newParticle.id, e);
const message = getErrorMessage(e); const message = getErrorMessage(e);
log_particle.error("id %s. send failed %s", newParticle.id, message);
item.onError( item.onError(
new SendError( new SendError(

View File

@ -16,18 +16,19 @@
import { fetchResource } from "@fluencelabs/js-client-isomorphic/fetcher"; import { fetchResource } from "@fluencelabs/js-client-isomorphic/fetcher";
import { getWorker } from "@fluencelabs/js-client-isomorphic/worker-resolver"; import { getWorker } from "@fluencelabs/js-client-isomorphic/worker-resolver";
import { Worker } from "@fluencelabs/threads/master"; import type { MarineBackgroundInterface } from "@fluencelabs/marine-worker";
import type { ModuleThread } from "@fluencelabs/threads/master";
type StrategyReturnType = [ type StrategyReturnType = [
marineJsWasm: ArrayBuffer, marineJsWasm: ArrayBuffer,
avmWasm: ArrayBuffer, avmWasm: ArrayBuffer,
worker: Worker, worker: ModuleThread<MarineBackgroundInterface>,
]; ];
export const loadMarineDeps = async ( export const loadMarineDeps = async (
CDNUrl: string, CDNUrl: string,
): Promise<StrategyReturnType> => { ): Promise<StrategyReturnType> => {
const [marineJsWasm, avmWasm] = await Promise.all([ const [marineJsWasm, avmWasm, worker] = await Promise.all([
fetchResource( fetchResource(
"@fluencelabs/marine-js", "@fluencelabs/marine-js",
"/dist/marine-js.wasm", "/dist/marine-js.wasm",
@ -38,10 +39,8 @@ export const loadMarineDeps = async (
fetchResource("@fluencelabs/avm", "/dist/avm.wasm", CDNUrl).then((res) => { fetchResource("@fluencelabs/avm", "/dist/avm.wasm", CDNUrl).then((res) => {
return res.arrayBuffer(); return res.arrayBuffer();
}), }),
getWorker("@fluencelabs/marine-worker", CDNUrl),
]); ]);
// TODO: load worker in parallel with avm and marine, test that it works
const worker = await getWorker("@fluencelabs/marine-worker", CDNUrl);
return [marineJsWasm, avmWasm, worker]; return [marineJsWasm, avmWasm, worker];
}; };

View File

@ -21,51 +21,29 @@ import type {
JSONValueNonNullable, JSONValueNonNullable,
CallParameters, CallParameters,
} from "@fluencelabs/marine-worker"; } from "@fluencelabs/marine-worker";
import { import { ModuleThread, Thread } from "@fluencelabs/threads/master";
ModuleThread,
Thread,
spawn,
Worker,
} from "@fluencelabs/threads/master";
import { MarineLogger, marineLogger } from "../../util/logger.js"; import { MarineLogger, marineLogger } from "../../util/logger.js";
import { IMarineHost } from "../interfaces.js"; import { IMarineHost } from "../interfaces.js";
export class MarineBackgroundRunner implements IMarineHost { export class MarineBackgroundRunner implements IMarineHost {
private workerThread?: ModuleThread<MarineBackgroundInterface>;
private loggers = new Map<string, MarineLogger>(); private loggers = new Map<string, MarineLogger>();
constructor( constructor(
private marineJsWasm: ArrayBuffer, private marineJsWasm: ArrayBuffer,
private avmWasm: ArrayBuffer, private avmWasm: ArrayBuffer,
private worker: Worker, private workerThread: ModuleThread<MarineBackgroundInterface>,
) {} ) {}
async hasService(serviceId: string) { async hasService(serviceId: string) {
if (this.workerThread === undefined) {
throw new Error("Worker is not initialized");
}
return this.workerThread.hasService(serviceId); return this.workerThread.hasService(serviceId);
} }
async removeService(serviceId: string) { async removeService(serviceId: string) {
if (this.workerThread === undefined) {
throw new Error("Worker is not initialized");
}
await this.workerThread.removeService(serviceId); await this.workerThread.removeService(serviceId);
} }
async start(): Promise<void> { async start(): Promise<void> {
if (this.workerThread !== undefined) {
throw new Error("Worker thread already initialized");
}
const workerThread: ModuleThread<MarineBackgroundInterface> =
await spawn<MarineBackgroundInterface>(this.worker);
const logfn: LogFunction = (message) => { const logfn: LogFunction = (message) => {
const serviceLogger = this.loggers.get(message.service); const serviceLogger = this.loggers.get(message.service);
@ -76,9 +54,8 @@ export class MarineBackgroundRunner implements IMarineHost {
serviceLogger[message.level](message.message); serviceLogger[message.level](message.message);
}; };
workerThread.onLogMessage().subscribe(logfn); this.workerThread.onLogMessage().subscribe(logfn);
await workerThread.init(this.marineJsWasm); await this.workerThread.init(this.marineJsWasm);
this.workerThread = workerThread;
await this.createService(this.avmWasm, "avm"); await this.createService(this.avmWasm, "avm");
} }
@ -86,10 +63,6 @@ export class MarineBackgroundRunner implements IMarineHost {
serviceModule: ArrayBuffer | SharedArrayBuffer, serviceModule: ArrayBuffer | SharedArrayBuffer,
serviceId: string, serviceId: string,
): Promise<void> { ): Promise<void> {
if (this.workerThread === undefined) {
throw new Error("Worker is not initialized");
}
this.loggers.set(serviceId, marineLogger(serviceId)); this.loggers.set(serviceId, marineLogger(serviceId));
await this.workerThread.createService(serviceModule, serviceId); await this.workerThread.createService(serviceModule, serviceId);
} }
@ -100,10 +73,6 @@ export class MarineBackgroundRunner implements IMarineHost {
args: Array<JSONValueNonNullable> | Record<string, JSONValueNonNullable>, args: Array<JSONValueNonNullable> | Record<string, JSONValueNonNullable>,
callParams?: CallParameters, callParams?: CallParameters,
): Promise<JSONValue> { ): Promise<JSONValue> {
if (this.workerThread === undefined) {
throw new Error("Worker is not initialized");
}
return this.workerThread.callService( return this.workerThread.callService(
serviceId, serviceId,
functionName, functionName,
@ -113,10 +82,6 @@ export class MarineBackgroundRunner implements IMarineHost {
} }
async stop(): Promise<void> { async stop(): Promise<void> {
if (this.workerThread === undefined) {
return;
}
await this.workerThread.terminate(); await this.workerThread.terminate();
await Thread.terminate(this.workerThread); await Thread.terminate(this.workerThread);
} }