Skip to content

Commit d1fad8b

Browse files
committed
Bump cats-effect to 3.6.0-RC1 and make the necessary changes accordingly.
1 parent 3a657cc commit d1fad8b

File tree

7 files changed

+1147
-27
lines changed

7 files changed

+1147
-27
lines changed

build.sbt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,15 @@ lazy val logbackMdcCatsEffect3 = module(ProjectName("logback-mdc-cats-effect3
327327
libraryDependencies ++= Seq(
328328
libs.logbackClassic,
329329
libs.logbackScalaInterop,
330-
libs.catsEffect3Eap,
330+
libs.catsEffect3,
331331
libs.tests.effectieCatsEffect3,
332332
libs.tests.extrasHedgehogCatsEffect3,
333333
) ++ libs.tests.hedgehogLibs,
334334
libraryDependencies := libraryDependenciesRemoveScala3Incompatible(
335335
scalaVersion.value,
336336
libraryDependencies.value,
337337
),
338-
javaOptions += "-Dcats.effect.ioLocalPropagation=true",
338+
javaOptions += "-Dcats.effect.trackFiberContext=true",
339339
)
340340
.dependsOn(
341341
core,
@@ -614,7 +614,7 @@ lazy val props =
614614

615615
final val CatsVersion = "2.7.0"
616616

617-
val CatsEffect3Version = "3.3.14"
617+
val CatsEffect3Version = "3.6.0-RC1"
618618

619619
val Monix3Version = "3.4.0"
620620

@@ -656,8 +656,6 @@ lazy val libs =
656656

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

659-
lazy val catsEffect3Eap = "org.typelevel" %% "cats-effect" % "3.6-02a43a6"
660-
661659
lazy val monix3Execution = "io.monix" %% "monix-execution" % props.Monix3Version
662660

663661
lazy val effectieCore: ModuleID = "io.kevinlee" %% "effectie-core" % props.EffectieVersion

modules/logger-f-logback-mdc-cats-effect3/shared/src/main/scala/loggerf/logger/logback/Ce3MdcAdapter.scala

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package loggerf.logger.logback
22

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

1918
private[this] val localContext: IOLocal[Map[String, String]] =
2019
IOLocal[Map[String, String]](Map.empty[String, String])
21-
.syncStep(1)
20+
.syncStep(100)
2221
.flatMap(
2322
_.leftMap(_ =>
2423
new Error(
@@ -28,27 +27,32 @@ class Ce3MdcAdapter extends JLoggerFMdcAdapter {
2827
)
2928
.unsafeRunSync()
3029

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

34-
@SuppressWarnings(Array("org.wartremover.warts.Null"))
35+
@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.StringPlusAny"))
3536
override def get(key: String): String =
36-
IOLocals.get(localContext).getOrElse(key, null) // scalafix:ok DisableSyntax.null
37+
localContext.unsafeThreadLocal().get.getOrElse(key, null) // scalafix:ok DisableSyntax.null
3738

38-
override def remove(key: String): Unit = IOLocals.update(localContext)(_ - key)
39+
override def remove(key: String): Unit = {
40+
val unsafeThreadLocal = localContext.unsafeThreadLocal()
41+
unsafeThreadLocal.set(unsafeThreadLocal.get - key)
42+
}
3943

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

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

4448
override def setContextMap0(contextMap: JMap[String, String]): Unit =
45-
IOLocals.set(localContext, contextMap.asScala.toMap)
49+
localContext.unsafeThreadLocal().set(contextMap.asScala.toMap)
4650

47-
private def getPropertyMap0: JMap[String, String] = IOLocals.get(localContext).asJava
51+
private def getPropertyMap0: JMap[String, String] = localContext.unsafeThreadLocal().get.asJava
4852

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

51-
override def getKeys: JSet[String] = IOLocals.get(localContext).keySet.asJava
55+
override def getKeys: JSet[String] = localContext.unsafeThreadLocal().get.keySet.asJava
5256

5357
}
5458
object Ce3MdcAdapter {
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package loggerf.logger.logback
2+
3+
import cats.effect.{IOLocal, unsafe}
4+
import ch.qos.logback.classic.LoggerContext
5+
import logback_scala_interop.JLoggerFMdcAdapter
6+
import org.slf4j.{LoggerFactory, MDC}
7+
8+
import java.util.{Map => JMap, Set => JSet}
9+
import scala.jdk.CollectionConverters._
10+
import scala.util.control.NonFatal
11+
12+
/** @author Kevin Lee
13+
* @since 2023-07-07
14+
*/
15+
class Ce3MdcAdapterWithIoRuntime(private val ioRuntime: unsafe.IORuntime) extends JLoggerFMdcAdapter {
16+
17+
private[this] val localContext: IOLocal[Map[String, String]] =
18+
IOLocal[Map[String, String]](Map.empty[String, String])
19+
.unsafeRunSync()(ioRuntime)
20+
21+
override def put(key: String, `val`: String): Unit = {
22+
val unsafeThreadLocal = localContext.unsafeThreadLocal()
23+
unsafeThreadLocal.set(unsafeThreadLocal.get + (key -> `val`))
24+
}
25+
26+
@SuppressWarnings(Array("org.wartremover.warts.Null", "org.wartremover.warts.StringPlusAny"))
27+
override def get(key: String): String =
28+
localContext.unsafeThreadLocal().get.getOrElse(key, null) // scalafix:ok DisableSyntax.null
29+
30+
override def remove(key: String): Unit = {
31+
val unsafeThreadLocal = localContext.unsafeThreadLocal()
32+
unsafeThreadLocal.set(unsafeThreadLocal.get - key)
33+
}
34+
35+
override def clear(): Unit = localContext.unsafeThreadLocal().set(Map.empty[String, String])
36+
37+
override def getCopyOfContextMap: JMap[String, String] = getPropertyMap0
38+
39+
override def setContextMap0(contextMap: JMap[String, String]): Unit =
40+
localContext.unsafeThreadLocal().set(contextMap.asScala.toMap)
41+
42+
private def getPropertyMap0: JMap[String, String] = localContext.unsafeThreadLocal().get.asJava
43+
44+
override def getPropertyMap: JMap[String, String] = getPropertyMap0
45+
46+
override def getKeys: JSet[String] = localContext.unsafeThreadLocal().get.keySet.asJava
47+
48+
}
49+
object Ce3MdcAdapterWithIoRuntime {
50+
51+
@SuppressWarnings(Array("org.wartremover.warts.Null"))
52+
private def initialize0(ioRuntime: unsafe.IORuntime): Ce3MdcAdapterWithIoRuntime = {
53+
val field = classOf[MDC].getDeclaredField("mdcAdapter")
54+
field.setAccessible(true)
55+
val adapter = new Ce3MdcAdapterWithIoRuntime(ioRuntime)
56+
field.set(null, adapter) // scalafix:ok DisableSyntax.null
57+
field.setAccessible(false)
58+
adapter
59+
}
60+
61+
@SuppressWarnings(Array("org.wartremover.warts.AsInstanceOf", "scalafix:DisableSyntax.asInstanceOf"))
62+
def initialize()(implicit ioRuntime: unsafe.IORuntime): Ce3MdcAdapterWithIoRuntime = {
63+
val loggerContext =
64+
LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]
65+
initializeWithLoggerContext(loggerContext)
66+
}
67+
68+
def initializeWithLoggerContext(
69+
loggerContext: LoggerContext
70+
)(implicit ioRuntime: unsafe.IORuntime): Ce3MdcAdapterWithIoRuntime = {
71+
val adapter = initialize0(ioRuntime)
72+
try {
73+
val field = classOf[LoggerContext].getDeclaredField("mdcAdapter")
74+
field.setAccessible(true)
75+
field.set(loggerContext, adapter)
76+
field.setAccessible(false)
77+
adapter
78+
} catch {
79+
case NonFatal(_) => adapter
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)