Skip to content

Commit ea54f59

Browse files
Michael Suttonjenkins
Michael Sutton
authored and
jenkins
committed
util/util-stats: scala 3 migration
**Problem** Build util-stats with Scala 3 **Solution** # Change util-stats project settings. # Compile project + test with Scala 3 migration flags # Remove flags # Fix incompatibilities # Run cross-building tests **Result** //Auto-rewrite fixes:// Scala 3 requires parentheses around the parameter of a lambda: - DelegatingStatsReceiverTest.scala //Other fixes:// Method `filterKeys` in trait MapOps is deprecated, should use .view.filterKeys: - CachedRegex.scala - CategorizingExceptionStatsHandlerTest.scala - MultiCategorizingExceptionStatsHandlerTest.scala `schemaKey` method must be called with `()`: - InMemoryStatsReceiver.scala Implicit conversion `long2float` in object Long is deprecated, need to be explicit: - Stat.scala - InMemoryStatsReceiverTest.scala - ExpressionSchemaTest.scala Cannot access apply method of case classes without specifying package: - Expression.scala Types in implicit definitions need to be given explicitly: - DelegatingStatsReceiverTest.scala Note: `print` changed to `println` in InMemoryStatsReceiver.scala to account for a Scala 3 bug where the split method does not work properly in string interpolation with special symbols. See https://jira.twitter.biz/browse/CSL-11259 JIRA Issues: CSL-11092 Differential Revision: https://phabricator.twitter.biz/D720514
1 parent 16a4a94 commit ea54f59

11 files changed

+61
-39
lines changed

CHANGELOG.rst

+10-6
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ Note that ``PHAB_ID=#`` and ``RB_ID=#`` correspond to associated messages in com
66

77
Unreleased
88
----------
9-
* util-routing: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D727120``
109

11-
* util-sl4j-jul-bridge: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D726468``
10+
New Features
11+
~~~~~~~~~~~~
1212

13-
* util-sl4j-api: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D725491``
13+
* util-cache: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D714304``.
1414

1515
* util-cache-guava: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D716101``.
1616

17-
* util-cache: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D714304``.
17+
* util-routing: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D727120``
18+
19+
* util-sl4j-api: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D725491``
20+
21+
* util-sl4j-jul-bridge: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D726468``
22+
23+
* util-stats: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D720514``
1824

19-
New Features
20-
~~~~~~~~~~~~
2125
* util-zk-test: Experimentally crossbuilds with Scala 3. ``PHAB_ID=D720603``
2226

2327
21.8.0 (No 21.7.0 Release)

build.sbt

+21-9
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,18 @@ def scalatestMockitoVersionedDep(scalaVersion: String) = {
229229
}
230230
}
231231

232+
def scalatestScalacheckVersionedDep(scalaVersion: String) = {
233+
if (scalaVersion.startsWith("2")) {
234+
Seq(
235+
"org.scalatestplus" %% "scalacheck-1-14" % "3.1.2.0" % "test"
236+
)
237+
} else {
238+
Seq(
239+
"org.scalatestplus" %% "scalacheck-1-15" % "3.2.9.0" % "test"
240+
)
241+
}
242+
}
243+
232244
lazy val util = Project(
233245
id = "util",
234246
base = file(".")
@@ -629,7 +641,7 @@ lazy val utilStats = Project(
629641
id = "util-stats",
630642
base = file("util-stats")
631643
).settings(
632-
sharedSettings
644+
sharedScala3EnabledSettings
633645
).settings(
634646
name := "util-stats",
635647
libraryDependencies ++= Seq(
@@ -638,16 +650,16 @@ lazy val utilStats = Project(
638650
scalacheckLib,
639651
"com.fasterxml.jackson.core" % "jackson-core" % jacksonVersion,
640652
"com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion,
641-
"com.fasterxml.jackson.module" %% "jackson-module-scala" % jacksonVersion exclude ("com.google.guava", "guava"),
642-
"org.mockito" % "mockito-core" % mockitoVersion % "test",
643-
"org.scalatestplus" %% "mockito-3-3" % "3.1.2.0" % "test",
644-
"org.scalatestplus" %% "scalacheck-1-14" % "3.1.2.0" % "test"
645-
) ++ {
653+
("com.fasterxml.jackson.module" %% "jackson-module-scala" % jacksonVersion exclude ("com.google.guava", "guava")).cross(CrossVersion.for3Use2_13),
654+
"org.mockito" % "mockito-core" % mockitoVersion % "test"
655+
) ++ scalatestMockitoVersionedDep(scalaVersion.value)
656+
++ scalatestScalacheckVersionedDep(scalaVersion.value)
657+
++ {
646658
CrossVersion.partialVersion(scalaVersion.value) match {
647-
case Some((2, major)) if major >= 13 =>
648-
Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.2.0" % "test")
649-
case _ =>
659+
case Some((2, major)) if major <= 12 =>
650660
Seq()
661+
case _ =>
662+
Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.3" % "test")
651663
}
652664
}
653665
).dependsOn(utilCore, utilLint)

util-stats/src/main/scala/com/twitter/finagle/stats/CachedRegex.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.twitter.finagle.stats
22

33
import java.util.concurrent.ConcurrentHashMap
44
import java.util.function.Consumer
5+
import scala.collection.compat._
56
import scala.util.matching.Regex
67

78
/**
@@ -50,6 +51,6 @@ private[stats] class CachedRegex(regex: Regex)
5051
}
5152
}
5253
})
53-
samples.filterKeys(filterFn).toMap
54+
samples.view.filterKeys(filterFn).toMap
5455
}
5556
}

util-stats/src/main/scala/com/twitter/finagle/stats/InMemoryStatsReceiver.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class InMemoryStatsReceiver extends StatsReceiver with WithHistogramDetails {
199199
p.println("---------")
200200
}
201201
for ((k, v) <- sortedCounters)
202-
p.print(f"$k%s $v%d\n")
202+
p.println(f"$k%s $v%d")
203203
if (includeHeaders && sortedGauges.nonEmpty) {
204204
p.println("\nGauges:")
205205
p.println("-------")
@@ -264,7 +264,7 @@ class InMemoryStatsReceiver extends StatsReceiver with WithHistogramDetails {
264264
* Designed to match the behavior of Metrics::registerExpression().
265265
*/
266266
override protected[finagle] def registerExpression(schema: ExpressionSchema): Unit = {
267-
expressions.put(schema.schemaKey, schema)
267+
expressions.put(schema.schemaKey(), schema)
268268
}
269269

270270
/**

util-stats/src/main/scala/com/twitter/finagle/stats/Stat.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object Stat {
3737
try {
3838
f
3939
} finally {
40-
stat.add(elapsed().inUnit(unit))
40+
stat.add(elapsed().inUnit(unit).toFloat)
4141
}
4242
}
4343

@@ -52,10 +52,12 @@ object Stat {
5252
def timeFuture[A](stat: Stat, unit: TimeUnit)(f: => Future[A]): Future[A] = {
5353
val start = Stopwatch.timeNanos()
5454
try {
55-
f.respond { _ => stat.add(unit.convert(Stopwatch.timeNanos() - start, TimeUnit.NANOSECONDS)) }
55+
f.respond { _ =>
56+
stat.add(unit.convert(Stopwatch.timeNanos() - start, TimeUnit.NANOSECONDS).toFloat)
57+
}
5658
} catch {
5759
case NonFatal(e) =>
58-
stat.add(unit.convert(Stopwatch.timeNanos() - start, TimeUnit.NANOSECONDS))
60+
stat.add(unit.convert(Stopwatch.timeNanos() - start, TimeUnit.NANOSECONDS).toFloat)
5961
Future.exception(e)
6062
}
6163
}

util-stats/src/main/scala/com/twitter/finagle/stats/exp/Expression.scala

+5-4
Original file line numberDiff line numberDiff line change
@@ -86,25 +86,26 @@ private[twitter] sealed trait Expression {
8686
/**
8787
* Represents a constant double number
8888
*/
89-
case class ConstantExpression private (repr: String) extends Expression
89+
case class ConstantExpression private[exp] (repr: String) extends Expression
9090

9191
/**
9292
* Represents compound metrics and their arithmetical(or others) calculations
9393
*/
94-
case class FunctionExpression private (fnName: String, exprs: Seq[Expression]) extends Expression {
94+
case class FunctionExpression private[exp] (fnName: String, exprs: Seq[Expression])
95+
extends Expression {
9596
require(exprs.size != 0, "Functions must have at least 1 argument")
9697
}
9798

9899
/**
99100
* Represents the leaf metrics
100101
*/
101-
case class MetricExpression private (metricBuilder: MetricBuilder) extends Expression
102+
case class MetricExpression private[exp] (metricBuilder: MetricBuilder) extends Expression
102103

103104
/**
104105
* Represent a histogram expression with specified component, for example the average, or a percentile
105106
* @param component either a [[HistogramComponent]] or a percentile in Double
106107
*/
107-
case class HistogramExpression private (
108+
case class HistogramExpression private[exp] (
108109
metricBuilder: MetricBuilder,
109110
component: Either[HistogramComponent, Double])
110111
extends Expression

util-stats/src/test/scala/com/twitter/finagle/stats/CategorizingExceptionStatsHandlerTest.scala

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.twitter.finagle.stats
22

33
import org.scalatest.funsuite.AnyFunSuite
4+
import scala.collection.compat._
45

56
class CategorizingExceptionStatsHandlerTest extends AnyFunSuite {
67
val categorizer = (t: Throwable) => { "clienterrors" }
@@ -19,9 +20,9 @@ class CategorizingExceptionStatsHandlerTest extends AnyFunSuite {
1920

2021
val keys = receiver.counters.keys.map(_.mkString("/")).toSeq.sorted
2122

22-
assert(receiver.counters.filterKeys(_.contains("failures")).size == 0)
23+
assert(receiver.counters.view.filterKeys(_.contains("failures")).size == 0)
2324

24-
assert(receiver.counters.filterKeys(_.contains("clienterrors")).size == 3)
25+
assert(receiver.counters.view.filterKeys(_.contains("clienterrors")).size == 3)
2526
assert(receiver.counters(Seq("clienterrors")) == 1)
2627
assert(receiver.counters(Seq("clienterrors", classOf[RuntimeException].getName)) == 1)
2728
assert(
@@ -30,7 +31,7 @@ class CategorizingExceptionStatsHandlerTest extends AnyFunSuite {
3031
) == 1
3132
)
3233

33-
assert(receiver.counters.filterKeys(_.contains("sourcedfailures")).size == 3)
34+
assert(receiver.counters.view.filterKeys(_.contains("sourcedfailures")).size == 3)
3435
assert(receiver.counters(Seq("sourcedfailures", "service")) == 1)
3536
assert(
3637
receiver.counters(Seq("sourcedfailures", "service", classOf[RuntimeException].getName)) == 1
@@ -67,8 +68,8 @@ class CategorizingExceptionStatsHandlerTest extends AnyFunSuite {
6768

6869
val keys = receiver.counters.keys.map(_.mkString("/")).toSeq.sorted
6970

70-
assert(receiver.counters.filterKeys(_.contains("failures")).size == 3)
71-
assert(receiver.counters.filterKeys(_.contains("sourcedfailures")).size == 0)
71+
assert(receiver.counters.view.filterKeys(_.contains("failures")).size == 3)
72+
assert(receiver.counters.view.filterKeys(_.contains("sourcedfailures")).size == 0)
7273

7374
assert(
7475
keys == Seq(
@@ -90,17 +91,17 @@ class CategorizingExceptionStatsHandlerTest extends AnyFunSuite {
9091

9192
val keys = receiver.counters.keys.map(_.mkString("/")).toSeq.sorted
9293

93-
assert(receiver.counters.filterKeys(_.contains("failures")).size == 0)
94+
assert(receiver.counters.view.filterKeys(_.contains("failures")).size == 0)
9495

95-
assert(receiver.counters.filterKeys(_.contains("clienterrors")).size == 2)
96+
assert(receiver.counters.view.filterKeys(_.contains("clienterrors")).size == 2)
9697
assert(receiver.counters(Seq("clienterrors")) == 1)
9798
assert(
9899
receiver.counters(
99100
Seq("clienterrors", classOf[RuntimeException].getName, classOf[Exception].getName)
100101
) == 1
101102
)
102103

103-
assert(receiver.counters.filterKeys(_.contains("sourcedfailures")).size == 2)
104+
assert(receiver.counters.view.filterKeys(_.contains("sourcedfailures")).size == 2)
104105
assert(receiver.counters(Seq("sourcedfailures", "service")) == 1)
105106
assert(
106107
receiver.counters(

util-stats/src/test/scala/com/twitter/finagle/stats/DelegatingStatsReceiverTest.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ class DelegatingStatsReceiverTest extends AnyFunSuite with ScalaCheckDrivenPrope
6464
Gen.oneOf(seq).flatMap(identity)
6565
}
6666

67-
implicit val impl = Arbitrary(Gen.delay(statsReceiverTopology(0)))
67+
implicit val impl: Arbitrary[StatsReceiver] = Arbitrary(Gen.delay(statsReceiverTopology(0)))
6868
}
6969

7070
test("DelegatingStatsReceiver.all collects effectively across many StatsReceivers") {
7171
val ctx = new Ctx
7272
import ctx._
7373

74-
forAll { statsReceiver: StatsReceiver =>
74+
forAll { (statsReceiver: StatsReceiver) =>
7575
assert(DelegatingStatsReceiver.all(statsReceiver).size == leafCounter)
7676
leafCounter = 0
7777
}

util-stats/src/test/scala/com/twitter/finagle/stats/InMemoryStatsReceiverTest.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class InMemoryStatsReceiverTest extends AnyFunSuite with Eventually with Integra
5858
test("ReadableGauge.toString") {
5959
var n = 0
6060
val stats = new InMemoryStatsReceiver()
61-
val g = stats.addGauge("a", "b") { n }
61+
val g = stats.addGauge("a", "b") { n.toFloat }
6262
assert("Gauge(a/b=0.0)" == g.toString)
6363

6464
n = 11

util-stats/src/test/scala/com/twitter/finagle/stats/MultiCategorizingExceptionStatsHandlerTest.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.twitter.finagle.stats
22

33
import org.scalatest.funsuite.AnyFunSuite
4+
import scala.collection.compat._
45

56
class MultiCategorizingExceptionStatsHandlerTest extends AnyFunSuite {
67
test("uses label, flags, source, exception chain and rolls up") {
@@ -141,8 +142,8 @@ class MultiCategorizingExceptionStatsHandlerTest extends AnyFunSuite {
141142

142143
val keys = receiver.counters.keys.map(_.mkString("/")).toSeq.sorted
143144

144-
assert(receiver.counters.filterKeys(_.contains("failures")).size == 3)
145-
assert(receiver.counters.filterKeys(_.contains("sourcedfailures")).size == 0)
145+
assert(receiver.counters.view.filterKeys(_.contains("failures")).size == 3)
146+
assert(receiver.counters.view.filterKeys(_.contains("sourcedfailures")).size == 0)
146147

147148
assert(
148149
keys == Seq(

util-stats/src/test/scala/com/twitter/finagle/stats/exp/ExpressionSchemaTest.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class ExpressionSchemaTest extends AnyFunSuite {
5656
case NonFatal(exn) =>
5757
failuresCounter.incr()
5858
} finally {
59-
latencyStat.add(elapsed().inMilliseconds)
59+
latencyStat.add(elapsed().inMilliseconds.toFloat)
6060
}
6161
}
6262
}

0 commit comments

Comments
 (0)