【问题标题】:Access variables in Gatling feeder with gRPC使用 gRPC 访问 Gatling feeder 中的变量
【发布时间】:2020-04-01 19:10:52
【问题描述】:

我正在尝试通过从 csv 文件中读取数据来创建我的 gRPC 有效负载(它有 guestID 和 category 作为列)。 我按照https://github.com/phiSgr/gatling-grpc/blob/244ab372da6773102d79c65a7e4086f409d3fe94/src/test/scala/com/github/phisgr/example/GrpcExample.scala 此处的示例进行操作,但在尝试相同操作时看到类型不匹配错误。 (它需要 Seq[ContextKey] 但在这里我能够形成 Seq[Expression[ContextKey]])

val scn2: ScenarioBuilder = scenario("gRPC call - 50 users repeated 100 times")
  .feed(csv("testtext.csv"))
  .exec(
    grpc("gRPC request with test message")
      .rpc(RecommenderGrpc.METHOD_GET_RECOMMENDATIONS)
      .payload(RequestContext.of(Map("test" -> "test"),
        Seq(ContextKey.defaultInstance.updateExpr(
          _.id :~ $("guestID"),
          _.`type` :~ Type.GUEST
        ), ContextKey.defaultInstance.updateExpr(
          _.id :~ $("category"),
          _.`type` :~ Type.CATEGORY
        )),
        Seq())
      )
  )

(payload是一个RequestContext对象,它接收元数据、keys和items。metadata是一个map,keys是一个ContextKey的Seq,items是空的Seq。ContextKey包含字符串guestID或者category和type)。

这里如何使用feeder中的变量?

【问题讨论】:

    标签: scala grpc gatling scala-gatling


    【解决方案1】:

    跳到底部寻找解决方案。


    Expression[T]Session => Validation[T] 的别名。用简单的英语来说,这是一个从会话中构造有效负载的函数,可能会失败。

    你可以考虑一个Expression[T],抽象地,“包含”一个T


    就像 JavaScript 中的 Promise 如何“包含”未来值一样。您不能将T 中的Promise 分配给需要T 的函数。如果要转换或组合Promises,则必须将代码从里到外翻转,并作为参数提供给.then1

    aPromise + 1 // wrong
    aPromise.then(a => a + 1)
    

    这与您的代码示例无法编译的原因相同。


    Gatling 的用户不一定熟悉 Scala 或一般的函数式编程。让他们理解这种“包装”的东西会适得其反。2所以有一些代码可以帮助你结合Expressions。

    对于 HTTP 和其他无类型的东西,EL string 在后台被解析并转换为 Expression

    Protobuf 消息是强类型的,无法使用字符串插值轻松构建有效负载。因此,镜头上的:~ 运算符用于处理管道,因此您不必手动处理Expression 包装。


    但是现在你有一个函数,RequestContext.of,它构造了有效载荷。如果您需要该功能,镜头魔法将无济于事。您必须自己编写 Expression lambda。3

    .payload { session =>
      for {
        guestId <- session("guestId").validate[String]
        category <- session("category").validate[String]
      } yield RequestContext.of(
        Map("test" -> "test"),
        Seq(
          ContextKey(id = guestID, `type` = Type.GUEST),
          ContextKey(id = category, `type` = Type.CATEGORY)
        ),
        Seq()
      )
    }
    

    1. 不用说这很繁琐,现在人们将 async-await 与 Promises 一起使用。

    2. Expression 只是 Either monad 和 Reader monad 堆叠在一起,有什么问题?

    3. 如果我知道RequestContext.of 的作用,我或许可以编写一个带镜头的版本。

    【讨论】:

    • 谢谢你,乔治。这对我有用` val scn2: ScenarioBuilder = scenario("gRPC call - multiple requests using feeder") .feed(csv("get_recs_data.csv").circular) .exec( grpc("gRPC request with test message") 。 rpc(RecommenderGrpc.METHOD_GET_RECOMMENDATIONS) .payload(session => RequestContext.of(metadata = Map("test" -> "test"), keys = Seq(ContextKey.of(session("guestID").as[String], Type.GUEST), ContextKey.of(session("category").as[String],Type.CATEGORY)), items = Seq()) ))`
    • 当我遇到它时,它的支持率为零,这是犯罪行为,因为 gatling grpc 文档中没有涵盖这一点,我整天都在努力寻找解决方案 :)
    • 好吧,很抱歉缺少文档。 :( 但在我的辩护中,我不希望一个拥有带有自定义 Scala 函数的代码库来创建有效负载的人需要一个操作“包装”对象的教程。
    猜你喜欢
    • 2019-02-10
    • 2022-01-14
    • 2016-08-20
    • 2018-11-14
    • 2022-08-18
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    相关资源
    最近更新 更多