-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
592 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package aqua | ||
|
||
import aqua.model.transform.TransformConfig | ||
import aqua.model.transform.res.FuncRes | ||
import aqua.types.Type | ||
|
||
import scala.concurrent.{ExecutionContext, Future, Promise} | ||
import scala.scalajs.js | ||
|
||
object CallJsFunction { | ||
|
||
// Register a service that returns no result | ||
def registerUnitService( | ||
peer: FluencePeer, | ||
serviceId: String, | ||
fnName: String, | ||
handler: (js.Array[js.Any]) => Unit | ||
) = { | ||
peer.internals.callServiceHandler.use((req, resp, next) => { | ||
if (req.serviceId == serviceId && req.fnName == fnName) { | ||
handler(req.args) | ||
resp.retCode = ResultCodes.success | ||
resp.result = new js.Object {} | ||
} | ||
|
||
next() | ||
}) | ||
} | ||
|
||
// Call a function with generated air script | ||
def funcCallJs( | ||
peer: FluencePeer, | ||
air: String, | ||
args: List[(String, js.Any)], | ||
returnType: Option[Type], | ||
config: TransformConfig | ||
)(implicit ec: ExecutionContext): Future[Any] = { | ||
val resultPromise: Promise[js.Any] = Promise[js.Any]() | ||
|
||
val requestBuilder = new RequestFlowBuilder() | ||
val relayPeerId = peer.getStatus().relayPeerId | ||
|
||
requestBuilder | ||
.disableInjections() | ||
.withRawScript(air) | ||
.configHandler((handler, r) => { | ||
handler.on(config.getDataService, config.relayVarName.getOrElse("-relay-"), (_, _) => { relayPeerId }) | ||
args.foreach { (fnName, arg) => | ||
handler.on(config.getDataService, fnName, (_, _) => arg) | ||
} | ||
handler.onEvent( | ||
config.callbackService, | ||
config.respFuncName, | ||
(args, _) => { | ||
if (args.length == 1) { | ||
resultPromise.success(args.pop()) | ||
} else if (args.length == 0) { | ||
resultPromise.success(()) | ||
} else { | ||
resultPromise.success(args) | ||
} | ||
() | ||
} | ||
) | ||
handler.onEvent( | ||
config.errorHandlingService, | ||
config.errorFuncName, | ||
(args, _) => { | ||
resultPromise.failure(new RuntimeException(args.pop().toString)) | ||
() | ||
} | ||
) | ||
}) | ||
.handleScriptError((err) => { | ||
resultPromise.failure(new RuntimeException("script error: " + err.toString)) | ||
}) | ||
.handleTimeout(() => { | ||
if (!resultPromise.isCompleted) | ||
resultPromise.failure(new RuntimeException(s"Request timed out")) | ||
}) | ||
|
||
peer.internals.initiateFlow(requestBuilder.build()).toFuture.flatMap { _ => | ||
returnType.fold(resultPromise.success(()).future)(_ => resultPromise.future) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package aqua | ||
|
||
import scala.concurrent.Promise | ||
import scala.scalajs.js | ||
import scala.scalajs.js.annotation.JSImport | ||
|
||
/*** | ||
* This is description of types from Fluence JS library. | ||
* See here for details https://github.com/fluencelabs/fluence-js | ||
*/ | ||
|
||
/** | ||
* Particle context. Contains additional information about particle which triggered `call` air instruction from AVM | ||
*/ | ||
trait ParticleContext { | ||
def particleId: String | ||
def initPeerId: String | ||
def timestamp: Int | ||
def ttl: Int | ||
def signature: String | ||
} | ||
|
||
object ResultCodes { | ||
val success = 0 | ||
val unknownError = 1 | ||
val exceptionInHandler = 2 | ||
} | ||
|
||
/** | ||
* Represents the result of the `call` air instruction to be returned into AVM | ||
*/ | ||
trait CallServiceResult extends js.Object { | ||
def retCode: Int | ||
def retCode_=(code: Int): Unit | ||
def result: js.Any | ||
def result_=(res: js.Any): Unit | ||
} | ||
|
||
/** | ||
* Represents the information passed from AVM when a `call` air instruction is executed on the local peer | ||
*/ | ||
trait CallServiceData extends js.Object { | ||
def serviceId: String | ||
def fnName: String | ||
def args: js.Array[js.Any] | ||
def particleContext: ParticleContext | ||
def tetraplets: js.Any | ||
} | ||
|
||
trait Internals extends js.Object { | ||
def initiateFlow(r: RequestFlow): js.Promise[js.Any] | ||
def callServiceHandler: CallServiceHandler | ||
} | ||
|
||
/** | ||
* Information about Fluence Peer connection | ||
*/ | ||
trait PeerStatus extends js.Object { | ||
def isInitialized: Boolean | ||
def isConnected: Boolean | ||
def peerId: String | ||
def relayPeerId: String | ||
} | ||
|
||
/** | ||
* This class implements the Fluence protocol for javascript-based environments. | ||
* It provides all the necessary features to communicate with Fluence network | ||
*/ | ||
@js.native | ||
@JSImport("@fluencelabs/fluence/dist/internal/compilerSupport/v1.js", "FluencePeer") | ||
class FluencePeer extends js.Object { | ||
val internals: Internals = js.native | ||
def getStatus(): PeerStatus = js.native | ||
def stop(): js.Promise[Unit] = js.native | ||
} | ||
|
||
/** | ||
* Public interface to Fluence JS SDK | ||
*/ | ||
@js.native | ||
@JSImport("@fluencelabs/fluence", "Fluence") | ||
object Fluence extends js.Object { | ||
def start(str: String): js.Promise[js.Any] = js.native | ||
def stop(): js.Promise[js.Any] = js.native | ||
def getPeer(): FluencePeer = js.native | ||
def getStatus(): PeerStatus = js.native | ||
} | ||
|
||
/** | ||
* Class defines the handling of a `call` air intruction executed by AVM on the local peer. | ||
* All the execution process is defined by the chain of middlewares - architecture popular among backend web frameworks. | ||
*/ | ||
@js.native | ||
@JSImport("@fluencelabs/fluence/dist/internal/compilerSupport/v1.js", "CallServiceHandler") | ||
class CallServiceHandler extends js.Object { | ||
|
||
def on( | ||
serviceId: String, | ||
fnName: String, | ||
handler: js.Function2[js.Array[js.Any], js.Any, js.Any] | ||
): js.Function0[CallServiceHandler] = js.native | ||
|
||
def onEvent( | ||
serviceId: String, | ||
fnName: String, | ||
handler: js.Function2[js.Array[js.Any], js.Any, js.Any] | ||
): js.Function0[CallServiceHandler] = js.native | ||
|
||
def use(f: js.Function3[CallServiceData, CallServiceResult, js.Function0[Unit], Unit]): CallServiceHandler = js.native | ||
} | ||
|
||
/** | ||
* The class represents the current view (and state) of distributed the particle execution process from client's point of view. | ||
* It stores the intermediate particles state during the process. RequestFlow is identified by the id of the particle that is executed during the flow. | ||
* Each RequestFlow contains a separate (unique to the current flow) CallServiceHandler where the handling of `call` AIR instruction takes place | ||
* Please note, that RequestFlow's is handler is combined with the handler from client before the execution occures. | ||
* After the combination middlewares from RequestFlow are executed before client handler's middlewares. | ||
*/ | ||
@js.native | ||
@JSImport("@fluencelabs/fluence/dist/internal/compilerSupport/v1.js", "RequestFlow") | ||
class RequestFlow extends js.Object {} | ||
|
||
/** | ||
* Builder class for configuring and creating Request Flows | ||
*/ | ||
@js.native | ||
@JSImport("@fluencelabs/fluence/dist/internal/compilerSupport/v1.js", "RequestFlowBuilder") | ||
class RequestFlowBuilder extends js.Object { | ||
def withRawScript(air: String): RequestFlowBuilder = js.native | ||
def configHandler(f: js.Function2[CallServiceHandler, js.Any, Unit]): RequestFlowBuilder = | ||
js.native | ||
def disableInjections(): RequestFlowBuilder = js.native | ||
def build(): RequestFlow = js.native | ||
def handleScriptError(f: js.Function1[js.Any, Unit]): RequestFlowBuilder = js.native | ||
def handleTimeout(f: js.Function0[Unit]): RequestFlowBuilder = js.native | ||
} |
Oops, something went wrong.