【问题标题】:How to chain Future's of client requests without nesting with onComplete?如何在不使用 onComplete 嵌套的情况下链接 Future 的客户端请求?
【发布时间】:2012-08-18 08:33:45
【问题描述】:

我需要查询一个总是返回 JSON 响应的 RESTful 服务。我需要联系它几次,总是提供一些我从上一个请求中学到的更多信息。我正在使用 Akka2、Scala、Jerkson 和 Spray-Can。

我目前的方法似乎可行,但它看起来很难看,并且需要嵌套所有内容。我读到应该有一些关于链接等可用的技术,但我不知道如何将它们应用到我当前的用例中。

这是我正在谈论的代码:

def discoverInitialConfig(hostname: String, bucket: String) = {

    val poolResponse: Future[HttpResponse] = 
      HttpDialog(httpClient, hostname, 8091)
      .send(HttpRequest(uri = "/pools"))
      .end

    poolResponse onComplete { 
      case Right(response) =>
        log.debug("Received the following global pools config: {}", response)

        val pool = parse[PoolsConfig](response.bodyAsString)
          .pools
          .find(_("name") == defaultPoolname)
          .get

        val selectedPoolResponse: Future[HttpResponse] =
          HttpDialog(httpClient, hostname, 8091)
          .send(HttpRequest(uri = pool("uri")))
          .end

        selectedPoolResponse onComplete {
          case Right(response) =>
            log.debug("Received the following pool config: {}", response)

            println(response.bodyAsString)

          case Left(failure) =>
            log.error("Could not load the pool config! {}", failure)
        }

      case Left(failure) =>
        log.error("Could not load the global pools config! {}", failure)
    }

我想你可以看到模式。联系 REST 服务,读取它,成功后将其解析为 JSON 案例类,提取信息然后进行下一次调用。

我这里的结构只有两层深,但我还需要添加第三层。

是否有可用的技术来改进它以获得更好的可读性,或者我只能坚持这个?如果您需要任何进一步的信息,我很乐意提供。你可以在这里看到完整的代码:https://github.com/daschl/cachakka/blob/f969d1f56a4c90a929de9c7ed4e4a0cccea5ba70/src/main/scala/com/cachakka/cluster/actors/InitialConfigLoader.scala

谢谢, 迈克尔

【问题讨论】:

    标签: scala spray


    【解决方案1】:

    HttpDialog 似乎完全涵盖了您的用例。

    【讨论】:

      【解决方案2】:

      我想我通过使用 spray-can 提供的 reply 方法找到了一条合理的捷径。

      def discoverInitialConfig(hostname: String, bucket: String) = {
      
      val poolResponse: Future[HttpResponse] = 
        HttpDialog(httpClient, hostname, 8091)
        .send(HttpRequest(uri = "/pools"))
        .reply(response => {
          log.debug("Received the following global pools config: {}", response)
          val selectedPool = parse[PoolsConfig](response.bodyAsString)
            .pools.find(_("name") == defaultPoolname).get
          HttpRequest(uri = selectedPool("uri"))
        })
        .reply(response => {
          log.debug("Received the following pool config: {}", response)
          println(response.bodyAsString)
          HttpRequest(uri = "/")
        })
        .end
      
      }
      

      如果这是可用的最佳方法,我会将其标记为“已回答”,但我渴望得到比我更了解这些内容的人的实际回复。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-03
        • 1970-01-01
        • 1970-01-01
        • 2017-05-10
        • 2014-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多