使用带有 OptionT[Future, _] 的显式执行上下文

瓦西戈克

我正在尝试编写一个自定义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]

代码 as is 编译,但只是因为我导入了隐式 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中的第二行实际上是一个可行的解决方案 - 我更新了代码块。

迪玛

不要过度使用猫。对于某些事情来说,它是一个很好的工具,但是如果使用不当,它只会增加复杂性并损害可读性,而没有任何好处。

    Future(getMaybeSnapshotFromMetadata(metadata))(streamDispatcher)
      .andThen { case _ => 
        observabilityService.recordWiseMetric(...)
      }(directorySnapshotScanningDispatcher) 
      .recoverWith(...)(streamDispatcher)

这相当于您的代码没有所有复杂性......这不是“解决方法”,而是编写此代码的实际正确方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

ApplicationLoader内部是否有隐式执行上下文

scala的执行上下文和播放的执行上下文之间有什么区别

具有上下文绑定的类型类隐式

使用golang在每个请求上执行上下文超时

ECMAScript 中的“一组 ECMAScript 执行上下文”和“执行上下文堆栈”有什么区别

使带有子上下文路径的嵌入式Spring Cloud Config Server

如果未在更新时指定所有上下文,为什么会执行所有上下文?

是否可以在其他上下文中使用带有响应(钩子)的上下文?

如何在静态上下文中使用带有上下文参数的类而不引起内存泄漏?

使用带有私有路由的上下文 API 响应登录

使用arrayController导致“没有托管对象上下文无法执行操作”

Next.js - 如何使用 Provider 来包装路由并使用带有钩子的上下文

使用getDefaultSharedPreferences,上下文有问题

使用正确的上下文

全局执行上下文是否有可能弹出执行堆栈?

React hooks & Context:在带有 useEffect 的子组件中使用上下文时出错

单击:在带有上下文对象的链接命令中使用其他功能

如何为提供者使用带有多个值的React Hooks上下文

使用带有HTML 5 Canvas的JQuery创建上下文菜单

如何在带有父级上下文的模块内使用require?

如何使用带有钩子的上下文进行身份验证?

使用带有取消的上下文,Go 例程不会终止

如何使用带有箭头函数的 filter() 数组的上下文参数

带有上下文的AsyncTask的Android startActivityForResult

弹性搜索加载带有上下文的 csv 数据

带有上下文本的按钮将不会单击

strace -p,带有上下文/历史的行数

重用带有context.WithTimeout的父上下文?

带有存储数据的 Firebase 存储上下文