我正在尝试将项目从猫效果 2 迁移到猫效果 3,我正在使用 doobie 与数据库进行交互。以前我可以ConnectionIO
像IO
描述的那样提升,但是随着升级我没有找到任何实现LiftIO[ConnectionIO]
,如何用 CE3 实现相同的目标?
2 回答
3
这里有两种方法。广义上讲,有“不要那样做”选项(推荐),另一种方法是使用WeakAsync
“不要那样做”
一般来说,不建议将任意代码交错IO
到ConnectionIO
程序中,因为ConnectionIO
它是事务性的,您无法回滚IO
. AConnectionIO
可能会运行多次,例如重试可恢复的故障。
如果可能,最好重构代码以不在事务内执行非事务性操作,而是在事后执行
但是,当这不切实际时,ConnectionIO
提供一个Sync
实例,因此您可以轻松地使用它做很多事情,而无需从IO
一开始就进行提升:
- 可以通过召唤来打印到控制台
Console[ConnectionIO]
- 获取当前时间可以通过
Clock[ConnectionIO]
Logger[ConnectionIO]
您可以根据需要使用适当的工厂为您的后端创建 log4cats- 生成 UUID 值可以通过
UUIDGen[ConnectionIO]
使用WeakAsync
Doobie'sWeakAsync
提供了一种获取Resource[F, F ~> ConnectionIO]
请注意,因为这是一个资源,所以您必须注意在其中完成事务use
-FunctionK
一旦完成,来自资源的生命周期将被关闭use
。
通常这意味着这样的事情:
def doStuff(rows: List[Int]): F[Unit] = ???
WeakAsync.liftK[F, ConnectionIO].use { fk =>
val transaction = for {
rows <- sql"select 1".query[Int].to[List]
_ <- fk(doStuff(rows))
} yield ()
transaction.transact(xa)
}
于 2022-02-24T20:03:26.250 回答
0
我找到了实现它的方法
def f()(implicit liftToConnectionIO: FunctionK[IO, ConnectionIO]): IO[Unit] = IO.unit
implicit val liftToConnectionIO = WeakAsync.liftK[IO, ConnectionIO]
liftToConnectionIO.use(implicit lift => f())
于 2022-02-21T20:03:58.930 回答