Monix Versions Save

Asynchronous, Reactive Programming for Scala and Scala.js.

v3.4.1

2 years ago

This is a minor bug-fixing release for the 3.x series.

Updated dependencies (#1554):

  • Scala compiler updated to 2.12.15, 2.13.8 and 3.1.2;
  • Typelevel Cats updated to 2.7.0;
  • Typelevel Cats-Effect updated to 2.5.4;
  • Updated compiler and sbt plugins to latest versions;

Fixes:

  • Trampoline.trampolineContext no longer ignores its parent BlockContext (#1544)
  • Only include JCTools in executionShadedJCTools (#1514)

This release was made possible by:

  • Alexandru Nedelcu (@alexandru)
  • Gabriele Petronella (@gabro)
  • Roman Janusz (@ghik)

v3.4.0

3 years ago

The release is binary and source compatible with 3.x series, and was cross-built for the following Scala and ScalaJS versions:

  • Scala 2.12, 2.13 and 3.0
  • Scala.js 1.5.1

WARN: we're dropping compatibility with Scala 2.11 and ScalaJS 0.6.x. If you still need those you'll have to stay on version 3.3.0.

Changes in this release:

  • Dropped support for Scala 2.11 and Scala.js 0.6.x
  • Dependency updates:
    • Cats 2.6.1
    • Cats-Effect 2.5.1
    • JCTools 3.3.0
  • Adds support for Scala 3 (#1326, #1327, #1328, #1329, #1344, #1323)
  • Adds Observable.whileBusyAggregateEvents (#1320)
  • Fix tracing in Coeval and Task via a more accurate filter (#1353)
  • Adds Observable.throttleLatest (#1396)
  • Implement pagination for Observable (#1381)

This release was made possible by the work and feedback of:

  • Alexandru Nedelcu (@alexandru)
  • Dominik Wosiński (@Wosin)
  • Lars Hupel (@larsrh)
  • Luke Stephenson (@lukestephenson)
  • Oleg Pyzhcov (@oleg-py)
  • Pau Alarcón (@paualarco)
  • Piotr Gawryś (@Avasil)

v3.3.0

3 years ago

The release is binary and source compatible with 3.x.x line. It is released for the following Scala and ScalaJS versions:

  • Scala 2.11: ScalaJS 0.6.x
  • Scala 2.12: ScalaJS 0.6.x and 1.3.x
  • Scala 2.13: ScalaJS 0.6.x and 1.3.x

Note that most likely, this is going to be the last release on ScalaJS 0.6.x. We can consider doing backports on-demand.

Highlights

Better Stack Traces

This release includes a highly requested feature of better stack traces for Task and Coeval! Big thanks to @RaasAhsan and @djspiewak for providing the original implementation that we have ported.

They are enabled by default, but it is configurable. Refer to Stack Traces section for more details.

We have measured about 10-30% performance hit in CACHED mode (the default) in microbenchmarks. If you have any performance tests, we would greatly appreciate any reports! If the hit is too big, you can disable the stack traces with -Dmonix.eval.stackTracingMode=none.

For the following code:

package test.app

import monix.eval.Task
import monix.execution.Scheduler
import cats.implicits._
import scala.concurrent.duration._

object TestTracingApp extends App {
  implicit val s = Scheduler.global

  def customMethod: Task[Unit] =
    Task.now(()).guarantee(Task.sleep(10.millis))

  val tracingTestApp: Task[Unit] = for {
    _ <- Task.shift
    _ <- Task.unit.attempt
    _ <- (Task(println("Started the program")), Task.unit).parTupled
    _ <- customMethod
    _ <- if (true) Task.raiseError(new Exception("boom")) else Task.unit
  } yield ()

  tracingTestApp.onErrorHandleWith(ex => Task(ex.printStackTrace())).runSyncUnsafe
}

The default (cached) stack trace is going to be:

java.lang.Exception: boom
        at test.app.TestTracingApp$.$anonfun$tracingTestApp$5(TestTracingApp.scala:36)
        at guarantee @ test.app.TestTracingApp$.customMethod(TestTracingApp.scala:29)
        at flatMap @ test.app.TestTracingApp$.$anonfun$tracingTestApp$4(TestTracingApp.scala:35)
        at parTupled @ test.app.TestTracingApp$.$anonfun$tracingTestApp$2(TestTracingApp.scala:34)
        at parTupled @ test.app.TestTracingApp$.$anonfun$tracingTestApp$2(TestTracingApp.scala:34)
        at flatMap @ test.app.TestTracingApp$.$anonfun$tracingTestApp$2(TestTracingApp.scala:34)
        at flatMap @ test.app.TestTracingApp$.$anonfun$tracingTestApp$1(TestTracingApp.scala:33)
        at flatMap @ test.app.TestTracingApp$.delayedEndpoint$test$app$TestTracingApp$1(TestTracingApp.scala:32)

Before 3.3.0 and with stack traces disabled, stack traces are a mess:

java.lang.Exception: boom
        at test.app.TestTracingApp$.$anonfun$tracingTestApp$5(TestTracingApp.scala:36)
        at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:188)
        at monix.eval.internal.TaskRestartCallback.syncOnSuccess(TaskRestartCallback.scala:101)
        at monix.eval.internal.TaskRestartCallback$$anon$1.run(TaskRestartCallback.scala:118)
        at monix.execution.internal.Trampoline.monix$execution$internal$Trampoline$$immediateLoop(Trampoline.scala:66)
        at monix.execution.internal.Trampoline.startLoop(Trampoline.scala:32)
        at monix.execution.schedulers.TrampolineExecutionContext$JVMNormalTrampoline.super$startLoop(TrampolineExecutionContext.scala:142)
        at monix.execution.schedulers.TrampolineExecutionContext$JVMNormalTrampoline.$anonfun$startLoop$1(TrampolineExecutionContext.scala:142)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
        at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94)
        at monix.execution.schedulers.TrampolineExecutionContext$JVMNormalTrampoline.startLoop(TrampolineExecutionContext.scala:142)
        at monix.execution.internal.Trampoline.execute(Trampoline.scala:40)
        at monix.execution.schedulers.TrampolineExecutionContext.execute(TrampolineExecutionContext.scala:57)
        at monix.execution.schedulers.BatchingScheduler.execute(BatchingScheduler.scala:50)
        at monix.execution.schedulers.BatchingScheduler.execute$(BatchingScheduler.scala:47)
        at monix.execution.schedulers.AsyncScheduler.execute(AsyncScheduler.scala:31)
        at monix.eval.internal.TaskRestartCallback.onSuccess(TaskRestartCallback.scala:72)
        at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:183)
        at monix.eval.internal.TaskRestartCallback.syncOnSuccess(TaskRestartCallback.scala:101)
        at monix.eval.internal.TaskRestartCallback.onSuccess(TaskRestartCallback.scala:74)
        at monix.eval.internal.TaskSleep$SleepRunnable.run(TaskSleep.scala:71)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Better Task => Future interop when using Local

Running Task isolates Local, which was not available in the Future, resulting in runToFuture. This release enables it and unblocks compelling use cases, such as reading proper request context in Akka HTTP Directive. We've created an AkkaHTTP Example that demonstrates it.

Latest behavior is:

implicit val s: Scheduler = Scheduler.Implicits.traced

val local = Local(0)

for {
  _  <- Task(local.update(1)).runToFuture
  value <- Future(local.get)
} yield println(s"Local value in Future $value")

println(s"Local value on the current thread = $value")

// => Local value on the current thread = 0
// => Local value in Future = 1

Task still isolates the Local, but the Future continuation keeps the same reference and can read it. Before the change, Local would be 0 in the Future.

More information about Local can be found in the new Local documentation.

Relevant updates

  • #1205: Observable.mergePrioritizedList
  • #1209: Bring back Observable.transform and Transformer alias
  • #1198: Fix flatMapIterable calling recursively itself
  • #1213: Propagate Local isolation in runToFuture
  • #1217: Fix performance regression in bufferSliding
  • #1244: Add support for compression: Gzip and deflate
  • #1262: Fix bug in Task.runSyncUnsafe related to ContextSwitch
  • #1265: Implement Observable#bufferWhile and bufferWhileInclusive
  • #1267: Implement Asynchronous Stack Traces for Task
  • #1276: Add Task/Coeval convenience methods like .when
  • #1282: Add 'as' in Task and Coeval
  • #1284: Add left/right builders for Task and Coeval
  • #1286: Add none/some builders for Task and Coeval
  • #1291: tapEval, tapError methods at Task and Coeval
  • #1293: removing no-op onComplete() in Observable.takeByTimespan
  • #1299: Fix a bug in Local.value
  • #1307: Observable.fromIteratorBuffered

People who made this release possible

  • Adrian (@adrian-salajan)
  • Alexandru Nedelcu (@alexelcu)
  • ctoomey (@ctoomey)
  • Dmitro Pochapsky (@pchpsky)
  • Georgy Khotyan (@GKhotyan)
  • James Yoo (@jyoo980)
  • Kasper Kondzielski (@ghostbuster91)
  • Pau Alarcón (@paualarco)
  • Piotr Gawryś (@Avasil)
  • Sandeep Kota (@sandeepkota)
  • tafit3 (@tafit3)
  • Vladyslav (@VladPodilnyk)

v3.2.2

3 years ago

The release is binary and source compatible with 3.x.x line. It is released for the following Scala and ScalaJS versions:

  • Scala 2.11: ScalaJS 0.6.x
  • Scala 2.12: ScalaJS 0.6.x and 1.0.x
  • Scala 2.13: ScalaJS 0.6.x and 1.0.x

Relevant updates:

  • #1197: Fixes a memory leak in bracket, introduced in 3.2.0
  • #1195: Fixes non-deterministic behavior in Observable.zip of sources different size
  • #1190: Now Observable.groupBy correctly signals error as a failed stream instead of normal completion
  • #1188: Fixes an issue in ForeachAsyncConsumer where it wasn't properly propagaing errors in some cases
  • #1187: Fixes an issue where Observable.doAfterSubscribe was not executing its finalizer
  • #1186: Observable.interval method now schedules the first tick asynchronously
  • #1184: Huge performance improvement in CharsReader, InputStream and LinesReaderObservable
  • #1154: Observable.fromInputStream and fromCharsReader now respects the chunkSize
  • #1181: Fix MatchError in Iterant.fromReactivePublisher

People who made this release possible:

  • Akosh Farkash (@aakoshh)
  • Alexander (@ppressives)
  • fnqista (@fnqista)
  • Kasper Kondzielski (@ghostbuster91)
  • Pau Alarcón (@paualarco)
  • Piotr Gawryś (@Avasil)
  • Vasily Kirichenko (@vasily-kirichenko)
  • Viktor Lövgren (@vlovgr)

v3.2.1

4 years ago

Bug fix release, fixing a critical issue with ScalaJS 1.0.x #1666 and a corner case with Bracket #1175

v3.2.0

4 years ago

The release is binary and source compatible with 3.x.x line. It is released for the following Scala and ScalaJS versions:

  • Scala 2.11: ScalaJS 0.6.x
  • Scala 2.12: ScalaJS 0.6.x and 1.0.x
  • Scala 2.13: ScalaJS 0.6.x and 1.0.x

Relevant updates:

  • #1087: Bracket should not evaluate "use" if Task was canceled during "acquire"
  • #1098: Allow to pass Long in Observable.drop(n)
  • #1101: Canceled tasks in Half-Open state should return to Open state in CircuitBreaker
  • #1107: Add CommutativeApplicative[Task.Par] instance
  • #1106 and #1125: Add Observable.concatMapIterable
  • #1117: SyncEffect instance for Coeval
  • #1120: Cancel should always wait for the finalizer
  • #1126: bufferIntrospective should signal Stop upstream when it is back-pressured
  • #1135: Observable.intervalAtFixedRate under-millisecond interval fix
  • #1132: Add Iterant.withFilter
  • #1129: Add Observable.withFilter
  • #1145: Deprecate gather, gatherN, gatherUnordered in favor of parSequence, parSequenceN, parSequenceUnordered
  • #1152: Add Consumer.toList

People that made this release possible:

  • Allan Timothy Leong (@allantl)
  • Eugene Platonov (@jozic)
  • Fabien Chaillou (@fchaillou)
  • Gabriel Claramunt (@gclaramunt)
  • Mantas Indrašius (@mantasindrasius)
  • TapanVaishnav (@TapanVaishnav)
  • najder-k (@najder-k)
  • Oleg Pyzhcov (@oleg-py)
  • Pau Alarcón (@paualarco)
  • Piotr Gawryś (@Avasil)
  • Ross A. Baker (@rossabaker)
  • Viet Yen Nguyen (@nguyenvietyen)
  • Viktor Dychko (@dychko)

v3.1.0

4 years ago

Version 3.1.0 (November 8, 2019)

The release is binary and source compatible with 3.0.0.

Important updates:

  • #1008: Fixed stack safety issue of Observable.combineLatestList for big lists
  • #1010: flatMapLoop for Task and Coeval
  • #1012: ConcurrentQueue.isEmpty
  • #1014: Observable.timeoutOnSlowDownstreamTo
  • #1016: Observable.takeUntilEval
  • #1057: Fix default scheduleOnce implementation
  • #1062: Solves a memory leak which sometimes occurred when using Task with localContextPropagation and non-TracingScheduler
  • #1063: Ensure async boundary in TaskCreate if LCP is enabled
  • #1064 and #1070: Earlier cancelation in Observable.mapParallel if any task fails
  • #1065: Add mapAccumulate to Observable

People that made this release possible:

  • Alexandru Nedelcu (@alexandru)
  • Allan Timothy Leong (@allantl)
  • fdilg (@fdilg)
  • Jan Bracker (@jbracker)
  • Moritz Bust (@busti)
  • mudsam (@mudsam)
  • Oleg Pyzhcov (@oleg-py)
  • Paweł Kiersznowski (@pk044)
  • Piotr Gawryś (@Avasil)
  • tanaka takaya (@takayahilton)
  • TapanVaishnav (@TapanVaishnav)

v3.0.0

4 years ago

This is the final release of Monix 3.0.0.

Important updates:

  • #875 and #1022: Update to Cats and Cats-Effect 2.0.0
  • #1018: Update Minitest to 2.7.0

Chores:

  • #996: improve Observable.publishSelector scaladoc
  • #1017: disable Scalafmt checks in build
  • #1006: Update sbt to 1.3.0
  • #1013: Update sbt-sonatype to 3.6

People that made this release possible:

  • Alexandru Nedelcu (@alexandru)
  • Oleg Pyzhcov (@oleg-py)
  • Piotr Gawryś (@Avasil)
  • The Cats and Cats-Effect contributors that worked on and released 2.0.0

v3.0.0-RC5

4 years ago

This is a bug fix release — fixing a critical issue:

  • #991 (PR #993): NullPointerException in Task when used in combination with Local
  • #992 (PR #998): hide InterceptableRunnable exposed accidentally, refactor it for efficiency
  • #997: bumped Scala version to 2.12.9 and Scala.js to 0.6.28

This release is binary compatible with 3.0.0-RC4.

v3.0.0-RC4

4 years ago

Version 3.0.0-RC4 (August 25, 2019)

Last release before 3.0.0 which will be released as soon as Cats-Effect 2.0.0 is available. At the time of writing release notes, it is only waiting on Cats 2.0.0 which is about to release next RC which will become stable version if no critical issues are discovered.

Any other development for this release is now frozen except if we discover critical bugs like memory leaks. All other changes will target 3.1.0.

3.0.0 will be binary and source compatible with 3.0.0-RC4 for Scala 2.12. Monix itself will be also binary compatible for 2.11 but it will have a dependency on Cats-Effect which is not. See Cats-Effect release notes for more details.

We wish we could release 3.0.0 already but if we released now, we would have to release 4.0.0 for Cats-Effect 2.0 because of 2.11 incompatibility there so we decided to hold on. It was a rough road but currently we have multiple active maintainers that can do releases going forward, instead of just Alex so we hope it can give you a confidence for the future! :) Note that Cats-Effect 2.0 is very small release and mostly targeted at support for Scala 2.13 and bug fixes - the upgrade should be limited to bumping version without changing a single line of code.

This release depends on Cats-Effect 1.4.0 and Cats 1.6.1

This release is binary compatible with 3.0.0-RC3 on Scala 2.12. On Scala 2.11 there is an incompatibility caused by introduction of Scheduler.features:

exclude[ReversedMissingMethodProblem]("monix.execution.Scheduler.features")

Main changes

Local

There are several fixes related to Local usage.

  • Using TracingScheduler will also automatically enable local context propagation in Task so running it with runToFutureOpt or setting env variable is no longer a necessity.
  • Local.isolate has a overload for isolating Future which is safer than regular Local.isolate.

The Local model since 3.0.0-RC3 shares by default. To isolate modifications of Local by other concurrently running Future, you have to call Local.isolate.

In case of Task, there is a TaskLocal.isolate version. It is automatically called whenever you run Task so if your use case is setting correlationId or similar, it probably won't require any explicit isolation because your HTTP library will most likely run the Task per request.

Task Builders

There are two major improvements:

  • Now all Task builders (Task.create, Task.async, Task.fromFuture etc.) will return a Task that continues on default Scheduler which is the one supplied during execution unless overriden by executeOn.
  • Callback in Task.create is now thread-safe against contract violation (calling it more than once) so does not require synchronization on the user side.

Sub-project: monix-execution

  • PR #946: Expose less implementation details in Local

  • PR #948: Make Task.memoize play well with Local

  • PR #953: Make default scheduler remove cancelled tasks

  • PR #960: Scheduler.features

  • PR #971: Callback tryOnSuccess/tryOnFailure

  • PR #973: Fix Local.isolate corner case

  • PR #977: Use type classes instead of overloads in Local.isolate/bind

Sub-project: monix-eval

  • PR #913: Optimize Task.guarantee

  • PR #921 & PR #917: Callbacks in Task.create are now thread-safe and always return to the main Scheduler.

  • PR #933: Adds >> syntax to Task

  • PR #935: Adds >> syntax to Coeval

  • PR #934: Implement doOnFinish in terms of guaranteeCase

  • PR #951: Add void to Task + Coeval

  • PR #952: Implement ContextShift.evalOn in terms of Task.executeOn

  • PR #954: Add gatherN + wanderN

  • PR #972: Rename Task.forkAndForget to Task.startAndForget

Sub-project: monix-reactive

  • PR #906: Fix race in MapParallelOrderedObservable

  • PR #918: switchMap should wait for last child to complete

  • PR #919: propagate cancellation to tasks in async Consumers

  • PR #932: Remove try-catch for EvalOnceObservable implementation

  • PR #941: Added some polymorphic methods for Observable

  • PR #945: Add collectWhile observable

  • PR #958: Add Observable.throttle

  • PR #963: Added fromAsyncStateActionF

  • PR #970: Observable.unfold

  • PR #989: Observable.unfoldEval and Observable.unfoldEvalF

Sub-project: monix-tail

  • PR #965: fixes resource handling in Iterant.repeat, adds Iterant.retryIfEmpty

Chores

Thanks

People that made this release possible, in alphabetical order:

  • Alexandru Nedelcu (@alexandru)
  • Allan Timothy Leong (@allantl)
  • BambooTuna (@BambooTuna)
  • Carlo (@entangled90)
  • Oleg Pyzhcov (@oleg-py)
  • Paul K (@pk044)
  • Piotr Gawryś (@Avasil)
  • Rahil Bohra (@rahilb)
  • Richard Tarczaly (@arlequin-nyc)
  • Ryo Fukumuro (@rfkm)
  • TapanVaishnav (@TapanVaishnav)
  • Valentin Willscher (@valenterry)