mirror of
https://github.com/fluencelabs/aqua.git
synced 2025-06-24 20:11:33 +00:00
feat(compiler): Generate empty calls to responseHandlerSrv
[LNG-286] (#979)
* Add noEmptyResponse * Fix tests
This commit is contained in:
2
api/api-npm/index.d.ts
vendored
2
api/api-npm/index.d.ts
vendored
@ -37,6 +37,8 @@ type CommonArgs = {
|
|||||||
targetType?: "ts" | "js" | "air" | undefined;
|
targetType?: "ts" | "js" | "air" | undefined;
|
||||||
/** Compile aqua in tracing mode (for debugging purposes). Default: false */
|
/** Compile aqua in tracing mode (for debugging purposes). Default: false */
|
||||||
tracing?: boolean | undefined;
|
tracing?: boolean | undefined;
|
||||||
|
/** Do not generate response call if there are no returned values */
|
||||||
|
noEmptyResponse?: boolean | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CodeString = {
|
type CodeString = {
|
||||||
|
@ -7,6 +7,7 @@ function getConfig({
|
|||||||
noXor = false,
|
noXor = false,
|
||||||
targetType = "air",
|
targetType = "air",
|
||||||
tracing = false,
|
tracing = false,
|
||||||
|
noEmptyResponse = false,
|
||||||
}) {
|
}) {
|
||||||
return new AquaConfig(
|
return new AquaConfig(
|
||||||
logLevel,
|
logLevel,
|
||||||
@ -19,6 +20,7 @@ function getConfig({
|
|||||||
air: "air",
|
air: "air",
|
||||||
}[targetType],
|
}[targetType],
|
||||||
tracing,
|
tracing,
|
||||||
|
noEmptyResponse,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@ import aqua.api.AquaAPIConfig
|
|||||||
import aqua.api.TargetType.*
|
import aqua.api.TargetType.*
|
||||||
import aqua.js.{FunctionDefJs, ServiceDefJs}
|
import aqua.js.{FunctionDefJs, ServiceDefJs}
|
||||||
import aqua.model.transform.TransformConfig
|
import aqua.model.transform.TransformConfig
|
||||||
|
|
||||||
import cats.data.Validated.{invalidNec, validNec}
|
import cats.data.Validated.{invalidNec, validNec}
|
||||||
import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec}
|
import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec}
|
||||||
|
|
||||||
import scala.scalajs.js
|
import scala.scalajs.js
|
||||||
import scala.scalajs.js.JSConverters.*
|
import scala.scalajs.js.JSConverters.*
|
||||||
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
|
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
|
||||||
@ -47,7 +47,9 @@ class AquaConfig(
|
|||||||
@JSExport
|
@JSExport
|
||||||
val targetType: js.UndefOr[String],
|
val targetType: js.UndefOr[String],
|
||||||
@JSExport
|
@JSExport
|
||||||
val tracing: js.UndefOr[Boolean]
|
val tracing: js.UndefOr[Boolean],
|
||||||
|
@JSExport
|
||||||
|
val noEmptyResponse: js.UndefOr[Boolean]
|
||||||
)
|
)
|
||||||
|
|
||||||
object AquaConfig {
|
object AquaConfig {
|
||||||
@ -69,7 +71,8 @@ object AquaConfig {
|
|||||||
constants = cjs.constants.map(_.toList).getOrElse(Nil),
|
constants = cjs.constants.map(_.toList).getOrElse(Nil),
|
||||||
noXor = cjs.noXor.getOrElse(false),
|
noXor = cjs.noXor.getOrElse(false),
|
||||||
noRelay = cjs.noRelay.getOrElse(false),
|
noRelay = cjs.noRelay.getOrElse(false),
|
||||||
tracing = cjs.tracing.getOrElse(false)
|
tracing = cjs.tracing.getOrElse(false),
|
||||||
|
noEmptyResponse = cjs.noEmptyResponse.getOrElse(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,14 @@ case class AquaAPIConfig(
|
|||||||
constants: List[String] = Nil,
|
constants: List[String] = Nil,
|
||||||
noXor: Boolean = false, // TODO: Remove
|
noXor: Boolean = false, // TODO: Remove
|
||||||
noRelay: Boolean = false,
|
noRelay: Boolean = false,
|
||||||
tracing: Boolean = false
|
tracing: Boolean = false,
|
||||||
|
noEmptyResponse: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
def getTransformConfig: TransformConfig = {
|
def getTransformConfig: TransformConfig = {
|
||||||
val config = TransformConfig(
|
val config = TransformConfig(
|
||||||
tracing = Option.when(tracing)(TransformConfig.TracingConfig.default)
|
tracing = Option.when(tracing)(TransformConfig.TracingConfig.default),
|
||||||
|
noEmptyResponse = noEmptyResponse
|
||||||
)
|
)
|
||||||
|
|
||||||
if (noRelay) config.copy(relayVarName = None)
|
if (noRelay) config.copy(relayVarName = None)
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package aqua.compiler
|
package aqua.compiler
|
||||||
|
|
||||||
import aqua.model.{CallModel, ForModel, FunctorModel, LiteralModel, ValueModel, VarModel}
|
import aqua.model.AquaContext
|
||||||
|
import aqua.model.CallServiceModel
|
||||||
|
import aqua.model.FlattenModel
|
||||||
import aqua.model.transform.ModelBuilder
|
import aqua.model.transform.ModelBuilder
|
||||||
import aqua.model.transform.TransformConfig
|
|
||||||
import aqua.model.transform.Transform
|
import aqua.model.transform.Transform
|
||||||
import aqua.parser.ParserError
|
import aqua.model.transform.TransformConfig
|
||||||
|
import aqua.model.{CallModel, ForModel, FunctorModel, LiteralModel, ValueModel, VarModel}
|
||||||
import aqua.parser.Ast
|
import aqua.parser.Ast
|
||||||
import aqua.parser.Parser
|
import aqua.parser.Parser
|
||||||
|
import aqua.parser.ParserError
|
||||||
import aqua.parser.lift.Span
|
import aqua.parser.lift.Span
|
||||||
import aqua.parser.lift.Span.S
|
import aqua.parser.lift.Span.S
|
||||||
import aqua.raw.ConstantRaw
|
import aqua.raw.ConstantRaw
|
||||||
@ -18,15 +21,12 @@ import aqua.types.{ArrayType, CanonStreamType, LiteralType, ScalarType, StreamTy
|
|||||||
import cats.Id
|
import cats.Id
|
||||||
import cats.data.{Chain, NonEmptyChain, NonEmptyMap, Validated, ValidatedNec}
|
import cats.data.{Chain, NonEmptyChain, NonEmptyMap, Validated, ValidatedNec}
|
||||||
import cats.instances.string.*
|
import cats.instances.string.*
|
||||||
import cats.syntax.show.*
|
|
||||||
import cats.syntax.option.*
|
|
||||||
import cats.syntax.either.*
|
import cats.syntax.either.*
|
||||||
|
import cats.syntax.option.*
|
||||||
|
import cats.syntax.show.*
|
||||||
|
import org.scalatest.Inside
|
||||||
import org.scalatest.flatspec.AnyFlatSpec
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
import org.scalatest.Inside
|
|
||||||
import aqua.model.AquaContext
|
|
||||||
import aqua.model.FlattenModel
|
|
||||||
import aqua.model.CallServiceModel
|
|
||||||
|
|
||||||
class AquaCompilerSpec extends AnyFlatSpec with Matchers with Inside {
|
class AquaCompilerSpec extends AnyFlatSpec with Matchers with Inside {
|
||||||
import ModelBuilder.*
|
import ModelBuilder.*
|
||||||
@ -358,7 +358,8 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers with Inside {
|
|||||||
join(VarModel(streamName, streamType), arg),
|
join(VarModel(streamName, streamType), arg),
|
||||||
decrement
|
decrement
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
emptyRespCall(transformCfg, initPeer)
|
||||||
),
|
),
|
||||||
errorCall(transformCfg, 0, initPeer)
|
errorCall(transformCfg, 0, initPeer)
|
||||||
)
|
)
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
package aqua.model.transform
|
package aqua.model.transform
|
||||||
|
|
||||||
|
import aqua.model.*
|
||||||
import aqua.model.inline.ArrowInliner
|
import aqua.model.inline.ArrowInliner
|
||||||
import aqua.model.inline.state.InliningState
|
import aqua.model.inline.state.InliningState
|
||||||
|
import aqua.model.transform.TransformConfig.TracingConfig
|
||||||
import aqua.model.transform.funcop.*
|
import aqua.model.transform.funcop.*
|
||||||
import aqua.model.transform.pre.*
|
import aqua.model.transform.pre.*
|
||||||
|
import aqua.model.transform.pre.{CallbackErrorHandler, ErrorHandler}
|
||||||
import aqua.model.transform.topology.Topology
|
import aqua.model.transform.topology.Topology
|
||||||
import aqua.model.*
|
|
||||||
import aqua.raw.ops.RawTag
|
import aqua.raw.ops.RawTag
|
||||||
import aqua.raw.value.VarRaw
|
import aqua.raw.value.VarRaw
|
||||||
import aqua.res.*
|
import aqua.res.*
|
||||||
import aqua.types.ScalarType
|
import aqua.types.ScalarType
|
||||||
import aqua.model.transform.TransformConfig.TracingConfig
|
|
||||||
import aqua.model.transform.pre.{CallbackErrorHandler, ErrorHandler}
|
|
||||||
|
|
||||||
import cats.Eval
|
import cats.Eval
|
||||||
import cats.data.Chain
|
import cats.data.Chain
|
||||||
import cats.free.Cofree
|
import cats.free.Cofree
|
||||||
|
import cats.instances.list.*
|
||||||
import cats.syntax.option.*
|
import cats.syntax.option.*
|
||||||
import cats.syntax.show.*
|
import cats.syntax.show.*
|
||||||
import cats.syntax.traverse.*
|
import cats.syntax.traverse.*
|
||||||
import cats.instances.list.*
|
|
||||||
import scribe.Logging
|
import scribe.Logging
|
||||||
|
|
||||||
// API for transforming RawTag to Res
|
// API for transforming RawTag to Res
|
||||||
@ -90,7 +90,8 @@ object Transform extends Logging {
|
|||||||
|
|
||||||
val resultsHandler: ResultsHandler = CallbackResultsHandler(
|
val resultsHandler: ResultsHandler = CallbackResultsHandler(
|
||||||
callbackSrvId = conf.callbackSrvId,
|
callbackSrvId = conf.callbackSrvId,
|
||||||
funcName = conf.respFuncName
|
funcName = conf.respFuncName,
|
||||||
|
noEmptyResponse = conf.noEmptyResponse
|
||||||
)
|
)
|
||||||
|
|
||||||
val errorHandler: ErrorHandler = CallbackErrorHandler(
|
val errorHandler: ErrorHandler = CallbackErrorHandler(
|
||||||
|
@ -1,19 +1,33 @@
|
|||||||
package aqua.model.transform
|
package aqua.model.transform
|
||||||
|
|
||||||
import aqua.model.{AquaContext, LiteralModel, ValueModel, VarModel}
|
import aqua.model.{AquaContext, LiteralModel, ValueModel, VarModel}
|
||||||
import aqua.raw.{ConstantRaw, RawContext, RawPart}
|
|
||||||
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
||||||
|
import aqua.raw.{ConstantRaw, RawContext, RawPart}
|
||||||
import aqua.types.ScalarType
|
import aqua.types.ScalarType
|
||||||
|
|
||||||
import cats.data.Chain
|
import cats.data.Chain
|
||||||
import cats.kernel.Monoid
|
import cats.kernel.Monoid
|
||||||
|
|
||||||
// TODO docs
|
/**
|
||||||
|
* Configuration for function pre transformer
|
||||||
|
*
|
||||||
|
* @param getDataService - name of the service that provides arguments
|
||||||
|
* @param callbackService - name of the service that provides callbacks
|
||||||
|
* @param errorHandlingService - name of the service that handles errors
|
||||||
|
* @param errorFuncName - name of the function that handles errors (in errorHandlingService)
|
||||||
|
* @param respFuncName - name of the function that handles responses (in getDataService)
|
||||||
|
* @param noEmptyResponse - if true, do not generate response call if there is no return values
|
||||||
|
* @param relayVarName - name of the relay variable
|
||||||
|
* @param tracing - tracing configuration
|
||||||
|
* @param constants - list of constants
|
||||||
|
*/
|
||||||
case class TransformConfig(
|
case class TransformConfig(
|
||||||
getDataService: String = "getDataSrv",
|
getDataService: String = "getDataSrv",
|
||||||
callbackService: String = "callbackSrv",
|
callbackService: String = "callbackSrv",
|
||||||
errorHandlingService: String = "errorHandlingSrv",
|
errorHandlingService: String = "errorHandlingSrv",
|
||||||
errorFuncName: String = "error",
|
errorFuncName: String = "error",
|
||||||
respFuncName: String = "response",
|
respFuncName: String = "response",
|
||||||
|
noEmptyResponse: Boolean = false,
|
||||||
relayVarName: Option[String] = Some("-relay-"),
|
relayVarName: Option[String] = Some("-relay-"),
|
||||||
tracing: Option[TransformConfig.TracingConfig] = None,
|
tracing: Option[TransformConfig.TracingConfig] = None,
|
||||||
constants: List[ConstantRaw] = Nil
|
constants: List[ConstantRaw] = Nil
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package aqua.model.transform.pre
|
package aqua.model.transform.pre
|
||||||
|
|
||||||
import aqua.types.Type
|
|
||||||
import aqua.raw.ops.{Call, CallArrowRawTag, RawTag}
|
import aqua.raw.ops.{Call, CallArrowRawTag, RawTag}
|
||||||
import aqua.raw.value.{ValueRaw, VarRaw}
|
import aqua.raw.value.{ValueRaw, VarRaw}
|
||||||
|
import aqua.types.Type
|
||||||
|
|
||||||
import cats.syntax.option.*
|
import cats.syntax.option.*
|
||||||
|
|
||||||
@ -10,11 +10,14 @@ trait ResultsHandler {
|
|||||||
def handleResults(results: List[(String, Type)]): Option[RawTag.Tree]
|
def handleResults(results: List[(String, Type)]): Option[RawTag.Tree]
|
||||||
}
|
}
|
||||||
|
|
||||||
case class CallbackResultsHandler(callbackSrvId: ValueRaw, funcName: String)
|
case class CallbackResultsHandler(
|
||||||
extends ResultsHandler {
|
callbackSrvId: ValueRaw,
|
||||||
|
funcName: String,
|
||||||
|
noEmptyResponse: Boolean
|
||||||
|
) extends ResultsHandler {
|
||||||
|
|
||||||
override def handleResults(results: List[(String, Type)]): Option[RawTag.Tree] =
|
override def handleResults(results: List[(String, Type)]): Option[RawTag.Tree] =
|
||||||
if (results.isEmpty) none
|
if (results.isEmpty && noEmptyResponse) none
|
||||||
else {
|
else {
|
||||||
val resultVars = results.map(VarRaw.apply.tupled)
|
val resultVars = results.map(VarRaw.apply.tupled)
|
||||||
val call = Call(
|
val call = Call(
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package aqua.model.transform
|
package aqua.model.transform
|
||||||
|
|
||||||
import aqua.model.*
|
import aqua.model.*
|
||||||
|
import aqua.model.FailModel
|
||||||
|
import aqua.model.IntoIndexModel
|
||||||
|
import aqua.model.OnModel
|
||||||
|
import aqua.model.inline.raw.StreamGateInliner
|
||||||
import aqua.raw.ops.Call
|
import aqua.raw.ops.Call
|
||||||
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
||||||
import aqua.{model, res}
|
|
||||||
import aqua.res.{CallRes, CallServiceRes, MakeRes}
|
|
||||||
import aqua.types.{ArrayType, LiteralType, ScalarType}
|
|
||||||
import aqua.types.StreamType
|
|
||||||
import aqua.model.IntoIndexModel
|
|
||||||
import aqua.model.inline.raw.StreamGateInliner
|
|
||||||
import aqua.model.OnModel
|
|
||||||
import aqua.model.FailModel
|
|
||||||
import aqua.res.ResolvedOp
|
import aqua.res.ResolvedOp
|
||||||
|
import aqua.res.{CallRes, CallServiceRes, MakeRes}
|
||||||
|
import aqua.types.StreamType
|
||||||
|
import aqua.types.{ArrayType, LiteralType, ScalarType}
|
||||||
|
import aqua.{model, res}
|
||||||
|
|
||||||
import scala.language.implicitConversions
|
|
||||||
import cats.data.Chain
|
import cats.data.Chain
|
||||||
import cats.data.Chain.==:
|
import cats.data.Chain.==:
|
||||||
import cats.syntax.option.*
|
import cats.syntax.option.*
|
||||||
|
import scala.language.implicitConversions
|
||||||
|
|
||||||
object ModelBuilder {
|
object ModelBuilder {
|
||||||
implicit def rawToValue(raw: ValueRaw): ValueModel = ValueModel.fromRaw(raw)
|
implicit def rawToValue(raw: ValueRaw): ValueModel = ValueModel.fromRaw(raw)
|
||||||
@ -88,15 +88,24 @@ object ModelBuilder {
|
|||||||
)
|
)
|
||||||
.leaf
|
.leaf
|
||||||
|
|
||||||
def respCall(bc: TransformConfig, value: ValueModel, on: ValueModel = initPeer) =
|
def respCallImpl(
|
||||||
res
|
config: TransformConfig,
|
||||||
.CallServiceRes(
|
arguments: List[ValueModel],
|
||||||
ValueModel.fromRaw(bc.callbackSrvId),
|
on: ValueModel = initPeer
|
||||||
bc.respFuncName,
|
) = res
|
||||||
CallRes(value :: Nil, None),
|
.CallServiceRes(
|
||||||
on
|
ValueModel.fromRaw(config.callbackSrvId),
|
||||||
)
|
config.respFuncName,
|
||||||
.leaf
|
CallRes(arguments, None),
|
||||||
|
on
|
||||||
|
)
|
||||||
|
.leaf
|
||||||
|
|
||||||
|
def respCall(config: TransformConfig, value: ValueModel, on: ValueModel = initPeer) =
|
||||||
|
respCallImpl(config, value :: Nil, on)
|
||||||
|
|
||||||
|
def emptyRespCall(config: TransformConfig, on: ValueModel = initPeer) =
|
||||||
|
respCallImpl(config, Nil)
|
||||||
|
|
||||||
def dataCall(bc: TransformConfig, name: String, on: ValueModel = initPeer) =
|
def dataCall(bc: TransformConfig, name: String, on: ValueModel = initPeer) =
|
||||||
res
|
res
|
||||||
|
@ -4,15 +4,15 @@ import aqua.model.transform.ModelBuilder
|
|||||||
import aqua.model.transform.{Transform, TransformConfig}
|
import aqua.model.transform.{Transform, TransformConfig}
|
||||||
import aqua.model.{CallModel, FuncArrow, LiteralModel, VarModel}
|
import aqua.model.{CallModel, FuncArrow, LiteralModel, VarModel}
|
||||||
import aqua.raw.ops.{Call, CallArrowRawTag, FuncOp, OnTag, RawTag, SeqTag}
|
import aqua.raw.ops.{Call, CallArrowRawTag, FuncOp, OnTag, RawTag, SeqTag}
|
||||||
import aqua.raw.value.{LiteralRaw, VarRaw}
|
|
||||||
import aqua.types.{ArrowType, NilType, ProductType, ScalarType}
|
|
||||||
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
||||||
|
import aqua.raw.value.{LiteralRaw, VarRaw}
|
||||||
import aqua.res.{CallRes, CallServiceRes, MakeRes, SeqRes, XorRes}
|
import aqua.res.{CallRes, CallServiceRes, MakeRes, SeqRes, XorRes}
|
||||||
|
import aqua.types.{ArrowType, NilType, ProductType, ScalarType}
|
||||||
|
|
||||||
import org.scalatest.flatspec.AnyFlatSpec
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
import cats.data.Chain
|
import cats.data.Chain
|
||||||
import cats.syntax.show.*
|
import cats.syntax.show.*
|
||||||
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
class TransformSpec extends AnyFlatSpec with Matchers {
|
class TransformSpec extends AnyFlatSpec with Matchers {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user