Skip to content

Commit

Permalink
Bump cats-effect to 3.6.0-RC1 and make the necessary changes accordin…
Browse files Browse the repository at this point in the history
…gly.
  • Loading branch information
kevin-lee committed Jan 2, 2025
1 parent cefd53a commit e937bf3
Show file tree
Hide file tree
Showing 7 changed files with 1,147 additions and 27 deletions.
8 changes: 3 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,15 @@ lazy val logbackMdcCatsEffect3 = module(ProjectName("logback-mdc-cats-effect3"),
libraryDependencies ++= Seq(
libs.logbackClassic,
libs.logbackScalaInterop,
libs.catsEffect3Eap,
libs.catsEffect3,
libs.tests.effectieCatsEffect3,
libs.tests.extrasHedgehogCatsEffect3,
) ++ libs.tests.hedgehogLibs,
libraryDependencies := libraryDependenciesRemoveScala3Incompatible(
scalaVersion.value,
libraryDependencies.value,
),
javaOptions += "-Dcats.effect.ioLocalPropagation=true",
javaOptions += "-Dcats.effect.trackFiberContext=true",
)
.dependsOn(
core,
Expand Down Expand Up @@ -572,7 +572,7 @@ lazy val props =

final val CatsVersion = "2.7.0"

val CatsEffect3Version = "3.3.14"
val CatsEffect3Version = "3.6.0-RC1"

val Monix3Version = "3.4.0"

Expand Down Expand Up @@ -607,8 +607,6 @@ lazy val libs =

lazy val catsEffect3 = "org.typelevel" %% "cats-effect" % props.CatsEffect3Version

lazy val catsEffect3Eap = "org.typelevel" %% "cats-effect" % "3.6-02a43a6"

lazy val monix3Execution = "io.monix" %% "monix-execution" % props.Monix3Version

lazy val effectieCore: ModuleID = "io.kevinlee" %% "effectie-core" % props.EffectieVersion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package loggerf.logger.logback

import cats.effect.unsafe.IOLocals
import cats.effect.{IOLocal, SyncIO}
import cats.syntax.all._
import ch.qos.logback.classic.LoggerContext
Expand All @@ -18,7 +17,7 @@ class Ce3MdcAdapter extends JLoggerFMdcAdapter {

private[this] val localContext: IOLocal[Map[String, String]] =
IOLocal[Map[String, String]](Map.empty[String, String])
.syncStep(1)
.syncStep(100)
.flatMap(
_.leftMap(_ =>
new Error(
Expand All @@ -28,27 +27,32 @@ class Ce3MdcAdapter extends JLoggerFMdcAdapter {
)
.unsafeRunSync()

override def put(key: String, `val`: String): Unit =
IOLocals.update(localContext)(_ + (key -> `val`))
override def put(key: String, `val`: String): Unit = {
val unsafeThreadLocal = localContext.unsafeThreadLocal()
unsafeThreadLocal.set(unsafeThreadLocal.get + (key -> `val`))
}

@SuppressWarnings(Array("org.wartremover.warts.Null"))
@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.StringPlusAny"))
override def get(key: String): String =
IOLocals.get(localContext).getOrElse(key, null) // scalafix:ok DisableSyntax.null
localContext.unsafeThreadLocal().get.getOrElse(key, null) // scalafix:ok DisableSyntax.null

override def remove(key: String): Unit = IOLocals.update(localContext)(_ - key)
override def remove(key: String): Unit = {
val unsafeThreadLocal = localContext.unsafeThreadLocal()
unsafeThreadLocal.set(unsafeThreadLocal.get - key)
}

override def clear(): Unit = IOLocals.reset(localContext)
override def clear(): Unit = localContext.unsafeThreadLocal().set(Map.empty[String, String])

override def getCopyOfContextMap: JMap[String, String] = getPropertyMap0

override def setContextMap0(contextMap: JMap[String, String]): Unit =
IOLocals.set(localContext, contextMap.asScala.toMap)
localContext.unsafeThreadLocal().set(contextMap.asScala.toMap)

private def getPropertyMap0: JMap[String, String] = IOLocals.get(localContext).asJava
private def getPropertyMap0: JMap[String, String] = localContext.unsafeThreadLocal().get.asJava

override def getPropertyMap: JMap[String, String] = getPropertyMap0

override def getKeys: JSet[String] = IOLocals.get(localContext).keySet.asJava
override def getKeys: JSet[String] = localContext.unsafeThreadLocal().get.keySet.asJava

}
object Ce3MdcAdapter {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package loggerf.logger.logback

import cats.effect.{IOLocal, unsafe}
import ch.qos.logback.classic.LoggerContext
import logback_scala_interop.JLoggerFMdcAdapter
import org.slf4j.{LoggerFactory, MDC}

import java.util.{Map => JMap, Set => JSet}
import scala.jdk.CollectionConverters._
import scala.util.control.NonFatal

/** @author Kevin Lee
* @since 2023-07-07
*/
class Ce3MdcAdapterWithIoRuntime(private val ioRuntime: unsafe.IORuntime) extends JLoggerFMdcAdapter {

private[this] val localContext: IOLocal[Map[String, String]] =
IOLocal[Map[String, String]](Map.empty[String, String])
.unsafeRunSync()(ioRuntime)

override def put(key: String, `val`: String): Unit = {
val unsafeThreadLocal = localContext.unsafeThreadLocal()
unsafeThreadLocal.set(unsafeThreadLocal.get + (key -> `val`))
}

@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.StringPlusAny"))
override def get(key: String): String =
localContext.unsafeThreadLocal().get.getOrElse(key, null) // scalafix:ok DisableSyntax.null

override def remove(key: String): Unit = {
val unsafeThreadLocal = localContext.unsafeThreadLocal()
unsafeThreadLocal.set(unsafeThreadLocal.get - key)
}

override def clear(): Unit = localContext.unsafeThreadLocal().set(Map.empty[String, String])

override def getCopyOfContextMap: JMap[String, String] = getPropertyMap0

override def setContextMap0(contextMap: JMap[String, String]): Unit =
localContext.unsafeThreadLocal().set(contextMap.asScala.toMap)

private def getPropertyMap0: JMap[String, String] = localContext.unsafeThreadLocal().get.asJava

override def getPropertyMap: JMap[String, String] = getPropertyMap0

override def getKeys: JSet[String] = localContext.unsafeThreadLocal().get.keySet.asJava

}
object Ce3MdcAdapterWithIoRuntime {

@SuppressWarnings(Array("org.wartremover.warts.Null"))
private def initialize0(ioRuntime: unsafe.IORuntime): Ce3MdcAdapterWithIoRuntime = {
val field = classOf[MDC].getDeclaredField("mdcAdapter")
field.setAccessible(true)
val adapter = new Ce3MdcAdapterWithIoRuntime(ioRuntime)
field.set(null, adapter) // scalafix:ok DisableSyntax.null
field.setAccessible(false)
adapter
}

@SuppressWarnings(Array("org.wartremover.warts.AsInstanceOf", "scalafix:DisableSyntax.asInstanceOf"))
def initialize()(implicit ioRuntime: unsafe.IORuntime): Ce3MdcAdapterWithIoRuntime = {
val loggerContext =
LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]
initializeWithLoggerContext(loggerContext)
}

def initializeWithLoggerContext(
loggerContext: LoggerContext
)(implicit ioRuntime: unsafe.IORuntime): Ce3MdcAdapterWithIoRuntime = {
val adapter = initialize0(ioRuntime)
try {
val field = classOf[LoggerContext].getDeclaredField("mdcAdapter")
field.setAccessible(true)
field.set(loggerContext, adapter)
field.setAccessible(false)
adapter
} catch {
case NonFatal(_) => adapter
}
}
}
Loading

0 comments on commit e937bf3

Please sign in to comment.