我正在嘗試撰寫一個自定義Akka SnapshotStore 插件。
我正處于要實作此方法的地步:
def loadAsync(persistenceId: String, criteria: SnapshotSelectionCriteria): Future[Option[SelectedSnapshot]]
這是我到目前為止所擁有的:
import cats.data.OptionT
import cats.implicits._
...
override def loadAsync(
persistenceId: String,
criteria: SnapshotSelectionCriteria
): Future[Option[SelectedSnapshot]] = {
// same as in the original plugin
val metadata = snapshotMetadatas(persistenceId, criteria).sorted.takeRight(maxLoadAttempts)
// need to get rid of this one!
import scala.concurrent.ExecutionContext.Implicits.global
val getSnapshotAndReportMetric = for {
snapshot <- OptionT.fromOption[Future](getMaybeSnapshotFromMetadata(metadata))
_ <- OptionT.liftF(Future {
observabilityService
.recordMetric(
LongCounterMetric(readVehicleSnapshotFromDiskCounter, SnapShotDirectoryScannerCommandOptions)
)
}(directorySnapshotScanningDispatcher))
} yield snapshot
getSnapshotAndReportMetric.value.recoverWith {
// retry if we listed an older snapshot that was deleted before loading
case _: NoSuchFileException => loadAsync(persistenceId, criteria)
}(streamDispatcher)
}
供參考的是 的簽名getMaybeSnapshotFromMetadata。它的簽名可以修改為添加一個Future,但最終包裝的回應必須是 type Option[SelectedSnapshot]。
private def getMaybeSnapshotFromMetadata(metadata: Seq[SnapshotMetadata]): Option[SelectedSnapshot]
代碼原樣編譯,但只是因為我匯入了隱式 global ExecutionContext。我的目標是使用不同的顯式執行背景關系(不同的可配置調度程式),但我不知道如何getMaybeSnapshotFromMetadata在 for-comprehensions 中為第一行(呼叫 的行)執行此操作。如果我使用OptionT.liftF,那么我可以做到,例如
...
snapshot <- OptionT.liftF( Future { getMaybeSnapshotFromMetadata(metadata)}(streamDispatcher))
...但后來我得到了OptionT[Future, Option[SelectedSnapshot]一個結果。
我想要實作的目標有解決方案嗎?如果不是,我可以只使用Futures 和它的andThen鏈方法:
Future {
getMaybeSnapshotFromMetadata(metadata)
}(streamDispatcher)
.andThen(selectedSnapshot => {
observabilityService
.recordMetric(
LongCounterMetric(readVehicleSnapshotFromDiskCounter, SnapShotDirectoryScannerCommandOptions)
)
selectedSnapshot
})(opentelemetryDispatcher)
.recoverWith {
// retry if we listed an older snapshot that was deleted before loading
case _: NoSuchFileException => loadAsync(persistenceId, criteria)
}(streamDispatcher)
更新對于理解liftF中的第二行實際上是一個可行的解決方案 - 我更新了代碼塊。
uj5u.com熱心網友回復:
不要過度使用貓。對于某些事情,它是一個很好的工具,但是如果使用不當,它只會增加復雜性并損害可讀性,而沒有任何好處。
Future(getMaybeSnapshotFromMetadata(metadata))(streamDispatcher)
.andThen { case _ =>
observabilityService.recordWiseMetric(...)
}(directorySnapshotScanningDispatcher)
.recoverWith(...)(streamDispatcher)
這相當于您的代碼沒有所有復雜性......這不是“解決方法”,而是撰寫此代碼的實際正確方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/493059.html
