【Scala】Future.sequence에서 실행되는 경우 원래 Seq의 순서가 유지되는지 확인

12355 단어 Scalatech

개요


Scara에서 비동기 프로세싱을 구현할 때Future가 사용됩니다.퓨처 기능으로는 여러 퓨처를 병렬로 수행하는 기능Future - 작업 협력 대상 파악 -에 소개된Future.sequence을 열거할 수 있다.
이것Future.sequence은 집행된 결과 원래의 Seq가 유지된 규격이 되었다.이것은 Asynchronous programming with Scala Futures의 글에서 소개한 내용이다.그래서 이 순서가 유지되는 것을 확인하고 비망록으로 보류했습니다.

확인 방법


같은 노드의 API에서 요청의 정렬 순서만 변경하고 (Seq로 가져오기) Future.sequence 에서 요청을 포기합니다.결과의 Seq부터 요청된 순서대로 정렬된 Seq와 동일한지 확인합니다.
또 확인용 API는 이번에 사용했다gBizINFO.

샘플


다음 원본을 확인한 결과도 순서를 유지했다.모든 소스 코드가 에 업로드되었습니다여기..
또 프레임은 AkkaHttp, JSON의 블라우스는 circe를 사용했다.
CompanySearchUseCase.scala

import akka.actor.ActorSystem
import companyInfo.model.api.InitialResponse
import companyInfo.model.rest.GbizResponse
import companyInfo.rest.CompanyRestClient
import companyInfo.rest.query.CompanyQueryBuilder
import io.circe.generic.auto._
import io.circe.parser._

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success}

object CompanySearchUseCase {

  implicit val system = ActorSystem()
  implicit val executionContext = system.dispatcher

  def getInitialDisplayCompanyInfo(): Either[Throwable, InitialResponse] = {
    // このソートキーでリクエストを投げる
    val sortKeys = Seq[String]("npmr", "roa", "roe", "equityRatio")

    val futureSeq = Future.sequence(sortKeys.map(k =>
    // APIリクエストを投げる処理(内容は記載を割愛)
    CompanyRestClient.sendRequestToGbiz(
      CompanyQueryBuilder.getQuery(sort = k)
    )))

    // 結果確認用のclass
    val initialRes = InitialResponse()
    var exceptionSeq = Seq.empty[Throwable]

    val result = Await.ready(futureSeq, Duration.Inf).value.get
    // sortKeysのSeqの順序になってるか確認する
    result.foreach(seq => seq.zipWithIndex.foreach(res => {
      res._1 match {
        case Success(r) => {
          decode[GbizResponse](r) match {
            case Right(bizRes) => {
              val companyResponses = bizRes.results.bindings.map(_.convertCompanyResponse())
	      // sortKeysの最初はnpmr
              if (res._2 == 0) {
                initialRes.byNpmrSortCompanies = companyResponses
	      // sortKeysの2番目はroa
              } else if (res._2 == 1) {
                initialRes.byRoaCompanies = companyResponses
	      // sortKeysの3番目はroe
              } else if (res._2 == 2) {
                initialRes.byRoeCompanies = companyResponses
	      // sortKeysの最後はequityRatio
              } else {
                initialRes.byEquityRatioCompanies = companyResponses
              }
            }
            case Left(ex) => exceptionSeq :+= ex
          }
        }
        case Failure(ex) => exceptionSeq :+= ex
      }
    }))

    if (exceptionSeq.isEmpty) {
      Right(initialRes)
    } else {
      Left(exceptionSeq.head)
    }
  }
}

좋은 웹페이지 즐겨찾기