From 95bb98a416aa0970fc4a029032ab0d875d9c21f3 Mon Sep 17 00:00:00 2001 From: Akim Mamedov Date: Wed, 13 Dec 2023 16:27:25 +0700 Subject: [PATCH 1/4] Add fire-and-forget flag --- packages/core/js-client/src/api.ts | 1 + .../core/js-client/src/compilerSupport/callFunction.ts | 7 ++++++- packages/core/js-client/src/jsPeer/FluencePeer.ts | 10 ++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/core/js-client/src/api.ts b/packages/core/js-client/src/api.ts index 87ca6a27b..845d2cf59 100644 --- a/packages/core/js-client/src/api.ts +++ b/packages/core/js-client/src/api.ts @@ -135,6 +135,7 @@ export const v5_callFunction = async ( peer: peerOrArg, args: callArgs, config, + fireAndForget: returnTypeVoid, }); if (returnTypeVoid) { diff --git a/packages/core/js-client/src/compilerSupport/callFunction.ts b/packages/core/js-client/src/compilerSupport/callFunction.ts index f07cc1074..0d57bbdc3 100644 --- a/packages/core/js-client/src/compilerSupport/callFunction.ts +++ b/packages/core/js-client/src/compilerSupport/callFunction.ts @@ -49,6 +49,7 @@ export type CallAquaFunctionArgs = { config?: CallAquaFunctionConfig | undefined; peer: FluencePeer; args: { [key: string]: JSONValue | ArgCallbackFunction }; + fireAndForget: boolean; }; export type CallAquaFunctionConfig = { @@ -60,6 +61,7 @@ export const callAquaFunction = async ({ config = {}, peer, args, + fireAndForget, }: CallAquaFunctionArgs) => { log.trace("calling aqua function %j", { script, config, args }); @@ -79,7 +81,10 @@ export const callAquaFunction = async ({ registerParticleScopeService(peer, particle, service); } - registerParticleScopeService(peer, particle, responseService(resolve)); + // If fire and forget not enabled, then JS client will wait for responseService call + if (!fireAndForget) { + registerParticleScopeService(peer, particle, responseService(resolve)); + } registerParticleScopeService(peer, particle, injectRelayService(peer)); diff --git a/packages/core/js-client/src/jsPeer/FluencePeer.ts b/packages/core/js-client/src/jsPeer/FluencePeer.ts index 7cd76f94c..24fe37a10 100644 --- a/packages/core/js-client/src/jsPeer/FluencePeer.ts +++ b/packages/core/js-client/src/jsPeer/FluencePeer.ts @@ -319,6 +319,13 @@ export abstract class FluencePeer { private isInitialized = false; private printParticleId = false; + private isFireAndForget(particleId: string) { + return ( + this.jsServiceHost.getHandler("callbackSrv", "response", particleId) === + null + ); + } + private _initServices() { this._classServices = { sig: new Sig(this.keyPair), @@ -601,6 +608,9 @@ export abstract class FluencePeer { if (item.result.callRequests.length > 0) { // TS doesn't allow to pass just 'item' void this.execCallRequests({ ...item, result: item.result }); + } else if (this.isFireAndForget(item.particle.id)) { + // Local work done. + item.onSuccess(null); } return connectionPromise; From 13f638421180bbb6c600de9f75420bc7134af70b Mon Sep 17 00:00:00 2001 From: Akim Mamedov Date: Wed, 13 Dec 2023 17:31:05 +0700 Subject: [PATCH 2/4] Fix test --- packages/core/js-client/src/api.spec.ts | 1 + packages/core/js-client/src/util/testUtils.ts | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/packages/core/js-client/src/api.spec.ts b/packages/core/js-client/src/api.spec.ts index 6abae83b6..e03e30e4a 100644 --- a/packages/core/js-client/src/api.spec.ts +++ b/packages/core/js-client/src/api.spec.ts @@ -76,6 +76,7 @@ describe("User API methods", () => { args: {}, peer, script, + fireAndForget: false, }); expect(res).toBe(7); diff --git a/packages/core/js-client/src/util/testUtils.ts b/packages/core/js-client/src/util/testUtils.ts index 6e502abba..8ba6a3de1 100644 --- a/packages/core/js-client/src/util/testUtils.ts +++ b/packages/core/js-client/src/util/testUtils.ts @@ -103,11 +103,18 @@ export const compileAqua = async (aquaFile: string): Promise => { const functions = Object.entries(compilationResult.functions) .map(([name, fnInfo]: [string, FunctionInfo]) => { const callFn = (peer: FluencePeer, args: PassedArgs) => { + const def = fnInfo.funcDef; + + const isReturnTypeVoid = + def.arrow.codomain.tag === "nil" || + def.arrow.codomain.items.length === 0; + return callAquaFunction({ script: fnInfo.script, config: {}, peer: peer, args, + fireAndForget: isReturnTypeVoid, }); }; From 4b8b02153c61636b7ece66ca038f7a84cc695cd4 Mon Sep 17 00:00:00 2001 From: Akim Mamedov Date: Wed, 13 Dec 2023 18:29:20 +0700 Subject: [PATCH 3/4] Store particle behavior in queue item --- .../js-client/src/compilerSupport/callFunction.ts | 7 ++----- packages/core/js-client/src/jsPeer/FluencePeer.ts | 12 ++++-------- packages/core/js-client/src/particle/Particle.ts | 1 + 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/core/js-client/src/compilerSupport/callFunction.ts b/packages/core/js-client/src/compilerSupport/callFunction.ts index 0d57bbdc3..1e2971e96 100644 --- a/packages/core/js-client/src/compilerSupport/callFunction.ts +++ b/packages/core/js-client/src/compilerSupport/callFunction.ts @@ -81,15 +81,12 @@ export const callAquaFunction = async ({ registerParticleScopeService(peer, particle, service); } - // If fire and forget not enabled, then JS client will wait for responseService call - if (!fireAndForget) { - registerParticleScopeService(peer, particle, responseService(resolve)); - } + registerParticleScopeService(peer, particle, responseService(resolve)); registerParticleScopeService(peer, particle, injectRelayService(peer)); registerParticleScopeService(peer, particle, errorHandlingService(reject)); - peer.internals.initiateParticle(particle, resolve, reject); + peer.internals.initiateParticle(particle, resolve, reject, fireAndForget); }); }; diff --git a/packages/core/js-client/src/jsPeer/FluencePeer.ts b/packages/core/js-client/src/jsPeer/FluencePeer.ts index 24fe37a10..bf1be4498 100644 --- a/packages/core/js-client/src/jsPeer/FluencePeer.ts +++ b/packages/core/js-client/src/jsPeer/FluencePeer.ts @@ -254,11 +254,13 @@ export abstract class FluencePeer { * @param particle - particle to start execution of * @param onSuccess - callback which is called when particle execution succeed * @param onError - callback which is called when particle execution fails + * @param fireAndForget - determines whether particle has fire-and-forget behavior */ initiateParticle: ( particle: IParticle, onSuccess: (result: JSONValue) => void, onError: (error: Error) => void, + fireAndForget: boolean, ): void => { if (!this.isInitialized) { throw new Error( @@ -277,6 +279,7 @@ export abstract class FluencePeer { callResults: [], onSuccess, onError, + fireAndForget, }); }, @@ -319,13 +322,6 @@ export abstract class FluencePeer { private isInitialized = false; private printParticleId = false; - private isFireAndForget(particleId: string) { - return ( - this.jsServiceHost.getHandler("callbackSrv", "response", particleId) === - null - ); - } - private _initServices() { this._classServices = { sig: new Sig(this.keyPair), @@ -608,7 +604,7 @@ export abstract class FluencePeer { if (item.result.callRequests.length > 0) { // TS doesn't allow to pass just 'item' void this.execCallRequests({ ...item, result: item.result }); - } else if (this.isFireAndForget(item.particle.id)) { + } else if (item.fireAndForget === true) { // Local work done. item.onSuccess(null); } diff --git a/packages/core/js-client/src/particle/Particle.ts b/packages/core/js-client/src/particle/Particle.ts index e9c41a9f3..cf3db44a9 100644 --- a/packages/core/js-client/src/particle/Particle.ts +++ b/packages/core/js-client/src/particle/Particle.ts @@ -187,6 +187,7 @@ export interface ParticleQueueItem { callResults: CallResultsArray; onSuccess: (result: JSONValue) => void; onError: (error: Error) => void; + fireAndForget?: boolean; } /** From 6db9e47709538d573b92cf904dce143cdd6efea2 Mon Sep 17 00:00:00 2001 From: Akim Mamedov Date: Fri, 15 Dec 2023 23:37:17 +0700 Subject: [PATCH 4/4] Fix tests --- packages/core/js-client/src/clientPeer/__test__/client.spec.ts | 2 +- packages/core/js-client/src/jsPeer/FluencePeer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/js-client/src/clientPeer/__test__/client.spec.ts b/packages/core/js-client/src/clientPeer/__test__/client.spec.ts index 4da9f9780..98af037fb 100644 --- a/packages/core/js-client/src/clientPeer/__test__/client.spec.ts +++ b/packages/core/js-client/src/clientPeer/__test__/client.spec.ts @@ -55,7 +55,7 @@ describe("FluenceClient usage test suite", () => { }, }); - peer.internals.initiateParticle(particle, resolve, reject); + peer.internals.initiateParticle(particle, resolve, reject, false); }); await expect(promise).rejects.toThrow(ExpirationError); diff --git a/packages/core/js-client/src/jsPeer/FluencePeer.ts b/packages/core/js-client/src/jsPeer/FluencePeer.ts index bf1be4498..28450dd5e 100644 --- a/packages/core/js-client/src/jsPeer/FluencePeer.ts +++ b/packages/core/js-client/src/jsPeer/FluencePeer.ts @@ -260,7 +260,7 @@ export abstract class FluencePeer { particle: IParticle, onSuccess: (result: JSONValue) => void, onError: (error: Error) => void, - fireAndForget: boolean, + fireAndForget: boolean = true, ): void => { if (!this.isInitialized) { throw new Error(