[英]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.