為什么會掛起?
import cats.effect.IO
import cats.effect.unsafe.implicits.global
import com.typesafe.config.ConfigFactory
import io.circe.config.parser
import org.typelevel.log4cats._
import org.typelevel.log4cats.slf4j._
object ItsElenApp extends App:
private val logger: SelfAwareStructuredLogger[IO] = LoggerFactory[IO].getLogger
val ops = for
_ <- logger.info("aa")
_ <- IO(println("bcc"))
_ <- logger.error("bb")
yield ()
ops.unsafeRunSync()
println("end")
它列印:
INFO 2022-06-19 11:56:25,303 ItsElenApp - aa
bcc
并繼續運行。是 log4cats 庫,還是我以錯誤的方式使用 App 物件。還是我必須關閉執行背景關系?
uj5u.com熱心網友回復:
運行cats.effect.IO基于應用程式的推薦方式是使用cats.effect.IOApp(或cats.effect.ResourceApp):
object MyApp extends IOApp:
// notice it takes List[String] rather than Array[String]
def run(args: List[String]): IO[ExitCode] = ...
這將運行應用程式,處理設定退出代碼等。它在到達 end時關閉應用程式run,如果默認執行緒池是非守護程式,這可能是必要的。如果您不想使用IOApp,您可能需要手動關閉 JVM,同時考慮到可能已在.unsafeRunSync().
App另一方面,一般不推薦擴展。為什么?它使用特殊Delayed機制,其中類的整個主體(其建構式)是惰性的。這使得對初始化的推理變得更加困難,這就是為什么這種機制被棄用/不鼓勵的原因。如果您不使用 IOApp,最好實作以下內容:
object MyProgram:
// Java requires this signature
def main(args: Array[String]): Unit = ...
在你的情況下可能看起來像
object ItsElenApp:
private val logger: SelfAwareStructuredLogger[IO] = LoggerFactory[IO].getLogger
def main(args: Array[String]): Unit =
val ops = for
_ <- logger.info("aa")
_ <- IO(println("bcc"))
_ <- logger.error("bb")
yield ()
// IOApp could spare you this
try
ops.unsafeRunSync()
finally
println("end")
sys.exit(0)
uj5u.com熱心網友回復:
因為 log4cats 的日志功能似乎是異步的。這意味著它們可能在不同的執行緒上運行,而不是與其他操作按順序運行。
這意味著主執行緒可能會完成,但其他執行緒會一直打開并且永遠不會關閉。
如果我使用ops.unsafeRunTimed(2.seconds)一切都會執行并關閉。但后面的日志行僅在時間結束時出現。看起來日志記錄有點懶惰,只有在被要求時才會完成。我不確定。
他們寫你不應該unsafeRunTimed在生產代碼中使用。
當然,如果你使用IOApp,一切都會再次正常執行。
但是,如果沒有IOApp. 我認為應該有一種干凈的方式來告訴 log4cats 完成操作,回傳它們的異步光纖結果并關閉所有內容。全部手動。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/493050.html
