Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .scala-steward.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ updates.ignore = [
{groupId = "org.scala-lang", artifactId = "scala-compiler", version = "2.13."},
{groupId = "org.scala-lang", artifactId = "scala-compiler", version = "3."}
]
updates.pin = [
{groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.9."}
]
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import com.softwaremill.Publish.ossPublishSettings

val scala212 = "2.12.19"
val scala213 = "2.13.18"
val scala30 = "3.4.1"
val scala3 = "3.9.0"

commonSmlBuildSettings
ossPublishSettings
Expand All @@ -28,13 +28,13 @@ lazy val retry = (projectMatrix in file("retry"))
)
)
.jvmPlatform(
scalaVersions = List(scala212, scala213, scala30),
scalaVersions = List(scala212, scala213, scala3),
settings = Seq(
scalacOptions ++= (if (ScalaArtifacts.isScala3(scalaVersion.value)) Seq.empty else Seq("-release", "8"))
scalacOptions ++= (if (ScalaArtifacts.isScala3(scalaVersion.value)) Seq("-release", "17") else Seq("-release", "8"))
)
)
.jsPlatform(
scalaVersions = List(scala212, scala213, scala30),
scalaVersions = List(scala212, scala213, scala3),
settings = Seq(
libraryDependencies += "io.github.cquiroz" %% "scala-java-time" % "2.5.0"
)
Expand Down
18 changes: 11 additions & 7 deletions retry/src/main/scala/Policy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,17 @@ trait CountingPolicy extends Policy {
// consider this successful if our predicate says so _or_
// we've reached the end out our countdown
val countedSuccess = success.or(max < 1)
retry(
promise,
() => orElse(max - 1),
{ (f: Future[T]) =>
if (max < 1) f else orElse(max - 1)
}
)(countedSuccess, executor)
locally {
// for scala 2 compatibility
implicit val success: Success[T] = countedSuccess
retry(
promise,
() => orElse(max - 1),
{ (f: Future[T]) =>
if (max < 1) f else orElse(max - 1)
}
)
}
}
}

Expand Down
21 changes: 11 additions & 10 deletions retry/src/test/scala/PolicySpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import scala.collection.compat.immutable.LazyList
import scala.concurrent.Future
import scala.concurrent.duration._

case class RetryAfter(duration: FiniteDuration) extends RuntimeException

abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {

// needed so we do not get a scalatest EC error
Expand Down Expand Up @@ -42,7 +44,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
it("should retry a future for a specified number of times") {
implicit val success = Success[Int](_ == 3)
val tries = forwardCountingFutureStream().iterator
Directly(3)(tries.next).map(result => assert(success.predicate(result) === true))
Directly(3)(tries.next()).map(result => assert(success.predicate(result) === true))
}

it("should fail when expected") {
Expand Down Expand Up @@ -114,7 +116,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
val marker_base = System.currentTimeMillis
val marker = new AtomicLong(0)

val runF = policy({ marker.set(System.currentTimeMillis); tries.next })
val runF = policy({ marker.set(System.currentTimeMillis); tries.next() })
runF.map { result =>
val delta = marker.get() - marker_base
assert(success.predicate(result) === true && delta >= 90) // was 110, depends on how hot runtime is
Expand Down Expand Up @@ -147,7 +149,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
val policy = Backoff(2, 30.millis)
val marker_base = System.currentTimeMillis
val marker = new AtomicLong(0)
val runF = policy({ marker.set(System.currentTimeMillis); tries.next })
val runF = policy({ marker.set(System.currentTimeMillis); tries.next() })
runF.map { result =>
val delta = marker.get() - marker_base
assert(success.predicate(result) === true && delta >= 90) // was 110
Expand Down Expand Up @@ -181,7 +183,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
implicit val algo: Jitter = algoCreator(10.millis)
val tries = forwardCountingFutureStream().iterator
val policy = JitterBackoff(3, 1.milli)
policy(tries.next).map(result => assert(success.predicate(result) === true))
policy(tries.next()).map(result => assert(success.predicate(result) === true))
}

it("should fail when expected") {
Expand Down Expand Up @@ -228,7 +230,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
val marker_base = System.currentTimeMillis
val marker = new AtomicLong(0)

policy({ marker.set(System.currentTimeMillis); tries.next }).map { result =>
policy({ marker.set(System.currentTimeMillis); tries.next() }).map { result =>
val delta = marker.get() - marker_base
assert(success.predicate(result) === true && delta >= 0)
}
Expand All @@ -242,7 +244,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
val marker_base = System.currentTimeMillis
val marker = new AtomicLong(0)

policy({ marker.set(System.currentTimeMillis); tries.next }).map { result =>
policy({ marker.set(System.currentTimeMillis); tries.next() }).map { result =>
val delta = marker.get() - marker_base
assert(success.predicate(result) === true && delta >= 0)
}
Expand Down Expand Up @@ -286,7 +288,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
Pause(delay = 2.seconds)
}
}
val future = policy(tries.next)
val future = policy(tries.next())
future.map(result => assert(success.predicate(result) === true))
}

Expand All @@ -299,13 +301,12 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
case 1 => Directly()
}

val future = policy(tries.next)
val future = policy(tries.next())
future.map(result => assert(success.predicate(result) === false))
}

it("should handle future failures") {
implicit val success = Success[Boolean](identity)
case class RetryAfter(duration: FiniteDuration) extends RuntimeException
val retried = new AtomicBoolean
def run() =
if (retried.get()) Future(true)
Expand Down Expand Up @@ -430,7 +431,7 @@ abstract class PolicySpec extends AsyncFunSpec with BeforeAndAfterAll {
val innerPolicy = Directly(3)
val future = FailFast(innerPolicy) { case _ =>
false
}(tries.next)
}(tries.next())
future.map(result => assert(success.predicate(result) === true))
}

Expand Down
Loading