Doobie - 将任意效果提升到 ConnectionIO CE3
Doobie - lifting arbitrary effect into ConnectionIO CE3
我正在尝试将项目从 cats-effect 2 迁移到 cats-effect 3,我正在使用 doobie 与数据库进行交互。以前我可以将 ConnectionIO
提升到 IO
,因为它是 ,但是随着升级我没有找到 LiftIO[ConnectionIO]
的任何实现,CE3 如何实现相同的?
我找到了实现方法
def f()(implicit liftToConnectionIO: FunctionK[IO, ConnectionIO]): IO[Unit] = IO.unit
implicit val liftToConnectionIO = WeakAsync.liftK[IO, ConnectionIO]
liftToConnectionIO.use(implicit lift => f())
这里有两种方法。一般来说,有“不要那样做”选项(推荐),另一种方法是使用 WeakAsync
“不要那样做”
通常,不建议将任意 IO
插入到 ConnectionIO
程序中,因为 ConnectionIO
是事务性的,您无法回滚 IO
。 ConnectionIO
可能 运行 多次,例如重试可恢复的故障。
如果可能,重构代码以不在事务内执行 non-transactional 操作,而是在事后执行它是个好主意
然而,当这不可行时,ConnectionIO
提供了一个 Sync
实例,因此您可以使用它轻松完成许多不需要从 [=12= 提升的事情] 第一名:
- 可以通过召唤
Console[ConnectionIO]
打印到控制台
- 获取当前时间可以用
Clock[ConnectionIO]
完成
- 您可以根据需要使用适合您后端的工厂创建 log4cats
Logger[ConnectionIO]
- 可以使用
UUIDGen[ConnectionIO]
生成 UUID 值
使用WeakAsync
Doobie 的 WeakAsync
提供了一种获取 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)
}
我正在尝试将项目从 cats-effect 2 迁移到 cats-effect 3,我正在使用 doobie 与数据库进行交互。以前我可以将 ConnectionIO
提升到 IO
,因为它是 LiftIO[ConnectionIO]
的任何实现,CE3 如何实现相同的?
我找到了实现方法
def f()(implicit liftToConnectionIO: FunctionK[IO, ConnectionIO]): IO[Unit] = IO.unit
implicit val liftToConnectionIO = WeakAsync.liftK[IO, ConnectionIO]
liftToConnectionIO.use(implicit lift => f())
这里有两种方法。一般来说,有“不要那样做”选项(推荐),另一种方法是使用 WeakAsync
“不要那样做”
通常,不建议将任意 IO
插入到 ConnectionIO
程序中,因为 ConnectionIO
是事务性的,您无法回滚 IO
。 ConnectionIO
可能 运行 多次,例如重试可恢复的故障。
如果可能,重构代码以不在事务内执行 non-transactional 操作,而是在事后执行它是个好主意
然而,当这不可行时,ConnectionIO
提供了一个 Sync
实例,因此您可以使用它轻松完成许多不需要从 [=12= 提升的事情] 第一名:
- 可以通过召唤
Console[ConnectionIO]
打印到控制台
- 获取当前时间可以用
Clock[ConnectionIO]
完成
- 您可以根据需要使用适合您后端的工厂创建 log4cats
Logger[ConnectionIO]
- 可以使用
UUIDGen[ConnectionIO]
生成 UUID 值
使用WeakAsync
Doobie 的 WeakAsync
提供了一种获取 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)
}