[英]Future of Iterable to run sequentially
帶解釋的代碼:
val partitions = preparePartitioningDataset(dataset, "sdp_id").map { partitions =>
val resultPartitionedDataset: Iterator[Future[Iterable[String]]] = for {
partition <- partitions
} yield {
val whereStatement = s"SDP_ID = '$partition'"
val partitionedDataset =
datasetService.getFullDatasetResultIterable(
dataset = dataset,
format = format._1,
limit = none[Int],
where = whereStatement.some
)
partitionedDataset
}
resultPartitionedDataset
}
partitions.map { partitionedDataset =>
for {
partition <- partitionedDataset
} notifyPartitionedDataset(
bearerToken = bearerToken,
endpoint = endpoint,
dataset = partition
)
}
所以現在
preparePartitioningDataset(dataset, "sdp_id")
返回一個Future[Iterator[String]]
datasetService.getFullDatasetResultIterable
自身也返回一個Future[Iterable[String]]
resultPartitionedDataset
是一個Iterator[Future[Iterable[String]]]
notifyPartitionedDataset
返回一個Future[Unit]
關於正在發生的事情和我正在努力實現的一些解釋
我有preparePartioningDataset
,它對單個值執行Select Distinct
,返回 Future[ResultSet] (映射到迭代器)。 這是因為對於每個單個值,我想執行SELECT * WHERE column=that_value
。 這發生在getFullDatasetResultIterable
上,同樣是 Future[ResultSet] 映射到迭代器。
最后一步是通過 POST 轉發我收到的每一個查詢。 它可以工作,但一切都是並行發生的(好吧,我想這就是為什么我想要 go 作為未來的原因),但現在我需要每個 POST( notifyPartionedDataset
)按順序發生,所以要一個接一個地發送一個帖子,而不是並行發送。
我嘗試了很多不同的方法,但我仍然得到相同的結果。
我怎么能往前走?
您可以利用IO
數據類型的惰性來確保某些操作按順序執行。
import cats.effect.IO
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def preparePartitioningDatasetIO(dataset: String, foo: String): IO[List[String]] =
IO.fromFuture(IO(
preparePartitioningDataset(dataset, foo))
)).map(_.toList)
def getFullDatasetResultIterableIO(dataset: String, format: String, limit: Option[Int], where: Option[String]): IO[List[String]] =
IO.fromFuture(IO(
datasetService.getFullDatasetResultIterable(
dataset,
format,
limit,
where
)
))
def notifyPartitionedDatasetIO(bearerToken: String, endpoint: String, dataset: List[String]): IO[Unit] =
IO.fromFuture(IO(
notifyPartitionedDataset(
bearerToken,
endpoint,
dataset
)
))
def program(dataset: String): IO[Unit] =
preparePartitioningDatasetIO(dataset, "sdp_id").flatMap { partitions =>
partitions.traverse_ { partition =>
val whereStatement = s"SDP_ID = '$partition'"
getFullDatasetResultIterableIO(
dataset = dataset,
format = format._1,
limit = none,
where = whereStatement.some
).flatMap { dataset =>
notifyPartitionedDatasetIO(
bearerToken = bearerToken,
endpoint = endpoint,
dataset = dataset
)
}
}
}
def run(dataset: String): Future[Unit] = {
import cats.effect.unsafe.implicits.global
program(dataset).unsafeToFuture()
}
代碼需要仔細審查和修復,尤其是函數的arguments。
但是,這應該有助於獲得您想要的結果,而無需重構整個代碼庫; 然而。
如果您希望getFullDatasetResultIterableIO
並行運行而notifyPartitionedDatasetIO
串行運行,您可以這樣做:
def program(dataset: String): IO[Unit] =
preparePartitioningDatasetIO(dataset, "sdp_id").flatMap { partitions =>
partitions.parTraverse { partition =>
val whereStatement = s"SDP_ID = '$partition'"
getFullDatasetResultIterableIO(
dataset = dataset,
format = format._1,
limit = none,
where = whereStatement.some
)
} flatMap { datasets =>
datasets.traverse_ { dataset =>
notifyPartitionedDatasetIO(
bearerToken = bearerToken,
endpoint = endpoint,
dataset = dataset
)
}
}
}
雖然這意味着在開始通知之前整個數據都保存在 memory 中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.