Monix: Version 2.2.2 Released
Version 2.2.2
is out now.
It is a minor release that’s binary and source compatible with 2.2.x
.
In summary:
- Implemented a circuit breaker for
Task
, for providing stability and preventing cascading failures in distributed systems - Added
Task!.memoizeOnSuccess
andCoeval!.memoizeOnSuccess
operators that only caches the result (with idempotency guarantees) for successful results, while re-evaluating the source on failures - Added
Task.deferFutureAction
that helps with wrappingFuture
-enabled APIs without requiringExecutionContext
in the function signature, sinceTask
can inject it for you - Added
SingleAssignmentCancelable.plusOne
for helping with buildingConsumer
objects - Moved and redesigned exceptions in
monix.execution
Task.sequence
now has lazy behavior in evaluating the given sequence (previously we were doing afoldLeft
on that sequence, which could have strict behavior, depending on the collection type)- Critical bugs fixed!
Details below!
New Features #
Issue #306 -
Introduced a circuit breaker in monix.eval.TaskCircuitBreaker
,
see documentation:
A circuit breaker is used to provide stability and prevent cascading failures in distributed systems:
import monix.eval._
import scala.concurrent.duration._
val circuitBreaker = TaskCircuitBreaker(
maxFailures = 5,
resetTimeout = 10.seconds
)
circuitBreaker.protect(problematicTask.timeout(1.second))
Issue #312 -
Introduced the Task!.memoizeOnSuccess
operator,
see documentation:
This Task!.memoizeOnSuccess
operator, caches the result (with
idempotency guarantees), just like the normal memoize
operator, only
it does so only on a successful result, whereas if failures happens,
subsequent calls will retry evaluating the source until it succeeds:
var effect = 0
val source = Task.eval {
effect += 1
if (effect < 3) throw new RuntimeException("dummy")
else effect
}
val cached = source.memoizeOnSuccess
val f1 = cached.runAsync // yields RuntimeException
val f2 = cached.runAsync // yields RuntimeException
val f3 = cached.runAsync // yields 3
val f4 = cached.runAsync // yields 3
Issue #313 -
On Task
we added the deferFutureAction
builder,
see documentation:
This helps with wrapping Future
-enabled APIs, by being able to
specify a callback with an injected Scheduler
:
def sumFuture(list: Seq[Int])(implicit ec: ExecutionContext): Future[Int] =
Future(list.sum)
// Look Ma, no implicit ExecutionContext!
def sumTask(list: Seq[Int]): Task[Int] =
Task.deferFutureAction { implicit scheduler =>
sumFuture(list)
}
Issue #325:
Added SingleAssignmentCancelable.plusOne
builder,
see documentation:
This plusOne
function builds a SingleAssignmentCancelable
reference which also cancels an extra cancelable specified at
construction time, in addition to the underlying cancelable that gets
assigned later:
val c = {
val guest = Cancelable(() => println("extra canceled"))
SingleAssignmentCancelable.plusOne(guest)
}
c := Cancelable(() => println("primary canceled"))
c.cancel()
//=> extra canceled
//=> primary canceled
This helps with building Consumer
objects that need to specify a
cancelable that cancels the data source, plus whatever resources
the consumer itself has opened.
List of Changes #
New Features and Enhancements:
- Issue #306:
Circuit Breaker for
Task
- Issue #312:
Add
Task.memoizeOnSuccess
andCoeval.memoizeOnSuccess
- Issue #313:
Add
Task.deferFutureAction
builder - Issue #325:
Add
SingleAssignmentCancelable.plusOne
- Issue #319:
Move and redesign exceptions in
monix.execution
- Issue #314:
Task.sequence
should have lazy behavior in evaluating the given sequence
Bug fixes:
- Bug #268:
Optimise the unsubscribe logic in
PublishSubject
- Bug #308:
Fix NPE on
AsyncSubject.unsubscribe
- Bug #315:
The
MapTaskObservable
internal object is exposed (ScalaDoc) - Bug #321:
Observable.concatMap
andmapTask
cannot be canceled if the source has already completed - Documentation fixes: #307, #309, #311, #316 and #317
Build:
- enabled the Scala
Migration Manager
(MiMa) in
build.sbt
to check for backwards compatibility problems - Issue #322:
Switch projects which use
CrossVersion.full/"org.scala-lang"
toCrossVersion.patch/scalaOrganization.value
Upgrading #
To use the new version, include this in your build.sbt
(and use
%%%
for Scala.js):
libraryDependencies += "io.monix" %% "monix" % "2.2.2"
The other projects from the @Monix organization have also been upgraded to depend on this new version.
shade, the Scala Memcached client:
dependencies += "io.monix" %% "shade" % "1.9.2"
monix-kafka, the Apache Kafka integration:
// For Kafka 8
libraryDependencies += "io.monix" %% "monix-kafka-8" % "0.11"
// For Kafka 9
libraryDependencies += "io.monix" %% "monix-kafka-9" % "0.11"
// For Kafka 10
libraryDependencies += "io.monix" %% "monix-kafka-10" % "0.11"
Enjoy!