Releases: getkyo/kyo
v1.0.0-RC2
v1.0.0-RC2
v1.0.0-RC2 is a large release. Nine new modules land, the HTTP stack is rewritten from scratch in pure Scala (with both client and server running on JVM, JS, and Native), and Scala Native picks up the remaining pieces it needed to be a viable target for everything Kyo ships 🚀
A recurring theme across the release is dependency reduction. Netty, libcurl, h2o, JCTools, Caffeine, HdrHistogram, the Java OpenTelemetry SDK, sttp, and tapir are all gone, replaced by pure-Scala implementations that share Kyo's scheduler and effect channels and compile to all three platforms. The new modules build directly on that foundation: durable workflows (kyo-flow), container orchestration (kyo-pod), feature flags (kyo-config), and OpenTelemetry export (kyo-stats-otlp) all rely almost exclusively on pure Scala implementations compiled to JVM, JS, and Native.
New Features
New modules
-
kyo-http(README) replaces the sttp and tapir integrations with a single client+server API that compiles to all three platforms, dropping Netty for a pure-Scala transport that handles TLS, WebSocket, Unix sockets, SSE, and NDJSON. Routes are an interpretable pure data structure with type-level field tracking viaRecord. (by @fwbrasil in #1479, #1518) -
kyo-pod(README) is a Docker and Podman client that talks the Docker Engine API directly over the Unix socket, with a shell execution fallback. Logs, stats, exec output, and image pulls stream from the first byte. Predefined containers for Postgres, MySQL, and MongoDB are provided for convenience. (by @fwbrasil in #1524) -
kyo-flow(README) is a durable workflow engine. AFlowis a plan, not an execution: every step is checkpointed before the next begins, and if the process crashes another executor claims the work via a time-limited lease and replays from the last checkpoint, skipping completed steps. Workflows suspend on declared inputs and resume when signals arrive through the engine API or the auto-generated HTTP endpoint, so human approval, async events, and other external triggers are first-class. Saga-style compensation, per-step retry and timeout, and an event audit trail are all built in. (by @fwbrasil in #1498) -
kyo-schema(README) is a single-source-of-truth schema module. DeriveSchema[A]from a case class and get JSON, Protobuf, type-safe lenses, structural diffs that ship and replay, batched mutations, incremental builders, and bidirectional conversions between structurally compatible types. No annotations, no boilerplate. The module depends only onkyo-dataand has no dependency on Kyo's effect runtime, so it can be adopted as a standalone library. (by @fwbrasil in #1517) -
kyo-parsemoves theParseeffect out ofkyo-preludeand parameterizes it on input type, so token-stream parsers compose with lexers. The internals are reworked to add error accumulation and AST recovery, which makes the effect suitable for real-world parsers like programming languages and LSPs. (by @Iltotore in #1305, #1404, #1421, @fwbrasil in #1400) -
kyo-config(README) provides typed feature flags and structured configuration.StaticFlagresolves once at class load for infrastructure settings;DynamicFlagevaluates per call for feature gates and A/B tests. Both support a rollout DSL with path matching, percentage weights, and deterministic bucketing, with automatic topology detection for K8s, AWS, and GCP. (by @fwbrasil in #1511) -
kyo-stats-otlpreplaces the JVM-onlykyo-stats-otelwith a from-scratch pure-Scala OTLP/HTTP exporter built onkyo-http. Speaks the protocol directly, runs on JVM, JS, and Native, and disables itself whenOTEL_EXPORTER_OTLP_ENDPOINTis unset. (by @fwbrasil in #1491) -
kyo-logging-jplandkyo-logging-slf4jare platform logging bridges extracted fromkyo-core.kyo-coreno longer pulls SLF4J as a dependency; pick whichever bridge matches your stack. (by @hygt in #1396)
Cross-platform process management
Path, Command, and Process now work consistently across JVM, JS, and Native, with safer APIs that drop java.* types in favor of Stream where it makes sense. The System effect also gains availableProcessors and architecture, classifying os.arch tokens consistently across platforms. (by @fwbrasil in #1505, #1522, #1532)
New primitives
-
Dictis a new low-allocation immutable map with a dual internal representation: a flatSpanfor up to 8 entries (linear scan, no hashing) and aHashMapabove that. Iteration takes separate key and value parameters to avoid boxing in hot paths. Used internally by the newRecordencoding. (by @fwbrasil in #1470, #1523) -
GatereplacesBarrierwith a primitive that covers both the cyclic-barrier and phaser use cases. Parties pass through together once everyone arrives, with multi-pass coordination and pass tracking; aGate.Dynamicvariant supports runtime join and leave plus hierarchical subgroups. (by @fwbrasil in #1480) -
Exchangeis a new low-level primitive for ID-multiplexed protocols like HTTP/2 and WebSocket subprotocols, where requests are tagged with an ID and responses are routed back by that ID. It encapsulates the pending-promise map, the reader fiber, the cleanup races, and backpressure for unsolicited events. Intended for protocol clients, not application code. (by @fwbrasil in #1501) -
New
Recordencoding: records no longer allow duplicate field names with different types. The old encoding stored a runtimeTagto disambiguate, which the new invariant plusConversion-based subtyping replaces, also reducing memory footprint. (by @fwbrasil in #1467, #1472) -
Base64: pure-Scala RFC 4648 implementation that cross-compiles to all three platforms without depending on
java.util.Base64. (by @fwbrasil in #1531)
Interop and convenience APIs
-
Kyo
Streamand ZIOZStreaminterop: bidirectional conversion between the two. (by @HollandDM in #1461) -
Abort.ignoreandAbort.loopUntil: two new error-handling combinators. (by @fwbrasil in #1507)
Improvements
Native parity
Scala Native catches up to JVM and JS on the modules where it used to be missing or partial. Full HTTP client and server support lands (by @fwbrasil in #1479), along with a JCTools queue port that replaces unoptimized stubs (by @fwbrasil in #1489), a Cache primitive that retires the JVM-only Caffeine dependency (by @fwbrasil in #1487), Prometheus and OTel-inspired histograms in kyo-stats that replace HdrHistogram (by @fwbrasil in #1483), signal handling so Native binaries respond to SIGINT and SIGTERM (by @hearnadam in #1408), and a scheduler jitter fix that addresses a Native-specific Thread.sleep contention (by @fwbrasil in #1485). reactive-streams now cross-compiles to JS and Native (by @fwbrasil in #1484), and the ZIO interop modules are enabled for Native (by @fwbrasil in #1482).
General
-
Scoped
Fiber.init: fibers used to be fire-and-forget by default, easy to lose track of.Fiber.initnow introduces aScopepending effect and registers a finalizer that interrupts the fiber when the scope closes.Fiber.initUnscopedpreserves the prior behavior. (by @johnhungerford in #1379) -
Reliable blocking detection and thread-interrupt propagation: the scheduler's stalled-worker detector now reads per-thread CPU time instead of thread state, which several kernel-level blocking operations leave at
RUNNABLEdespite genuinely being blocked. Fiber interrupts also reach into truly blocking I/O likeServerSocket.acceptnow: the JVM thread interrupt is dispatched, gated to fire only when the worker is genuinely parked so it can't damage in-flight work. (by @fwbrasil in #1510) -
Nested
.nowand.laterindirect:.nowand.laterinside another.now, and.laterinside another.later, now compile, removing a common ergonomic wart. (by @ahoy-jon in #1369) -
ConcreteTagderivation for unions and intersections: generic methods overAbort[E | Closed]compil...
Kyo 1.0-RC1: A New Era of Simplicity and Stability
We're excited to announce that Kyo is finally entering a period of API stabilization! 🚀 Over the past three years, we've quickly iterated on the abstractions of the library to ensure they're reliable and provide a good user experience, but adopting Kyo was challenging due to the constant breaking changes. The project has now reached a level of maturity where we're comfortable making a commitment regarding stability. The 1.0-RC1 release is the first in a series of releases meant as a final validation of the APIs before reaching the 1.0.0 release.
During the RC cycle, the project will maintain source compatibility and, for cases where an incompatible change proves important, we'll provide Scalafix rewrite rules. Paired with Kyo's mature set of primitives, adopting the library for production systems becomes a viable option. The duration of this period will depend on how much feedback we get, so bug reports, feature requests, and general feedback on the library are greatly appreciated 🙏
We're also proud to announce the core developers team leading the project. @hearnadam is now Lead Maintainer and we welcomed @ahoy-jon to the team!
- Flavio Brasil - Creator of Kyo 🚀
- Adam Hearn - Lead maintainer 👁️
- John Hungerford - Deep owner of Combinators and Streams 🥄
- Jonathan Winandy - Direct Style Magician 🔮
- Jason Pickens - Cooking up kyo-grpc 👨🍳
Improvements
-
Mature streaming: As mentioned in previous release notes, finalizing the
StreamAPIs was a major focus to enable the RC cycle. This release includes several major improvements. Enabled by the newTagimplementation, all related APIs now provide proper variance. A newPipeAPI was introduced to express streaming transformations in isolation, a pair ofhandleandunwrapmethods was introduced to facilitate the management of the pending set, and other new methods were introduced:stream.groupedWithin,stream.broadcast,Stream.fromIterator, andStream.fromIteratorCatching. (by @johnhungerford in #1254, #1259, #1268, #1268, #1274, #1281, #1166, #1170, #1239, #1238, @ahoy-jon in #1222, #1251, #1244, #1255) -
Deeper ZIO integration: The
kyo-ziomodule now provides bi-directional transformations between Kyo's and ZIO's layers and streams. (by @hearnadam in #1299, @HollandDM #1298) -
Direct syntax overhaul: The direct syntax had a series of major fixes and improvements, greatly improving its usability. New integrations with dotty-cps-async's
AsyncShiftenable transformations using.nowin functions for collection types,Maybe, and multiple issues with edge cases were fixed. (by @ahoy-jon in #1197, #1212, #1202, #1235, #1204, #1303, #1310, #1311) -
Better resource safety: Kyo's default APIs used to not register finalizers automatically. In this release,
Channel,Meter,Hub, andQueueautomatically register finalizers in theinitmethod and a new set ofinitUnscopedmethods is provided to initialize without finalizers. Additionally, finalizers are able to inspect errors when executing and an edge case with finalization backpressure got fixed. (by @johnhungerford in #1313, #1322, #1324, @fwbrasil in #1194) -
Effectful fibers and simplified isolates: Fibers used to have two type parameters representing the possible successful or failure outcomes without being able to express other pending effects like
Streamand other APIs do. This release changes it toFiber[+A, -S]whereSrepresents a pending effect set. To enable this change, contextual and stateful isolates were merged into a singleIsolate[Remove, -Keep, Restore]. When forking, the proper isolate is automatically inferred and anyRestoreeffects are added to the pendingSset of the theFiber. -
Async improvements: Fibers used to change identity on each asynchronous boundary, which prevented the implementation of some features. Fibers now keep a stable identity until completion. A new
Async.raceFirstmethod has been added,Async.timeoutwas improved to better handle timeouts with zero duration, and theTimeoutexception now shows the timeout duration. (by @fwbrasil in #1190, @hearnadam in #1229, #1340, #1225) -
Channel draining and closing on empty: Channels didn't have a convenient way for a producer to handle termination. In this release, a new
closeAndWaitEmptyenables an atomic close once the channel is empty,pendingPutsandpendingTakesprovide full visibility of the state of the channel, and streaming from channels was optimized via internal optimistic draining. (by @fwbrasil in #1191, #1203, @steinybot in #1193, #1264) -
Kyo companion: The
Kyocompanion object provides APIs for common operations. Its collection methods now keep the original collection types instead of just returningChunkand a new set ofKyo.whencombinators provides convenient composition of branching logic. (by @HollandDM in #1218, @johnhungerford in #1304) -
Data structures improvements:
Recordnow offers agetFieldmethod to enable access of fields with special or reserved names andChunknow has alastMaybemethod. (by @road21 in #1201, #1187, @steinybot in #1226) -
Lifting usability: Kyo's automatic lifting of values had an edge case where it prevented value discard warnings in the direct syntax that got fixed. Also, there was a usability issue with IDEs suggesting lifting of companion objects, which doesn't make sense. The lifting was changed to not allow lifting of companion objects. (by @ahoy-jon in #1314, #1291)
-
Parameterized generic aspects: The
Aspecteffect couldn't be used in scenarios where the aspect has a parameterized generic parameter. The effect was changed to operate on tags instead of object instances to overcome the limitation. (by @fwbrasil in #1327) -
Combinators cleanups: The zipping combinators now use a
Zippabletype to automatically flatten multiple zipped computations, theensuringmethod was fixed to acceptAbort[Throwable], and several cleanups were made in the APIs. (by @hearnadam in #1295, #1336, #1337, @johnhungerford in #1319, @ahoy-jon in #1307) -
Scalafix migration rules: The initial setup of Scalafix rewrites was done to support the RC cycle and rules to facilitate the migration from
0.19.0to1.0-RC1were added.
Breaking changes
- The
IOeffect was renamed toSync. (by @ahoy-jon in #1277) Resourcewas renamed toScope. (by @hearnadam in #1356)IO.applyandAsync.applywere renamed toIO.deferandAsync.defer. (by @fwbrasil in #1308, #1309)Async.runwas moved toFiber.init,Async.runAndBlockmoved toKyoApp.runAndBlock. (by @fwbrasil in #1316)fromCompletionStagemoved fromFibertoAsync(by @fwbrasil in #1195)KArraywas renamed toSpan. (by @fwbrasil in #1326)SafeClassTagwas renamed toConcreteTag. (by @fwbrasil in #1329)- In
kyo-direct, thedefermethod was renamed todirect. (by @ahoy-jon in #1236) Choice.evalnow takes a vararg param. (by @ahoy-jon in #1219)TScheduleremoved inkyo-stm. (by @fwbrasil in #1331)- Scala 2.12 support was dropped. (@ahoy-jon in #1266)
New Contributors
v0.19.0
This is the last release before we start a new 1.0 release candidate cycle! Yes, you heard that right. We know we've been breaking our APIs like... a lot 😅 but we feel we're finally ready to start making commitments regarding stability. The next release will be 1.0-RC1 and we'll have a series of releases (hopefully in a single digit) to validate our commitments regarding the APIs that the library will provide in the long term. During this period, we'll do our best to maintain source compatibility and, for cases where some breaking change is important, we're planning to provide scalafix rewrites.
Kyo 1.0 here we gooooo!!!! 🚀
New features and improvements
First-class support for computation nesting: Kyo uses an optimized internal representation for computations that is able to represent regular values as computations without a wrapper object, avoiding allocations in case there are no effect suspensions. This internal characteristic used to leak to user-facing APIs via a Flat evidence, which used to provide a way to ensure the value of a computation wasn't itself another computation. In this release, this limitation has been lifted! Flat has been removed and nesting is encoded as an internal concern of the kernel. When plain values are lifted to computations, if a nested computation is detected, an internal wrapper object is instantiated to provide proper nesting, following a pattern similar to Maybe and Result. This change improves usability to define new effects and facilitates integration with other libraries since it enables free use of Kyo in generic contexts, including effect handling, without the requirement of a Flat evidence. (by @fwbrasil in #1148)
New Tag: Kyo's Tag used to have a number of limitations. It was designed to avoid allocations by leveraging bytecode-defined strings and to enable the definition and use of Kyo's current set of effects, but it couldn't represent all Scala types, including not handling variance. This limitation required effects like Env to use erased tags and less-safe effect handling internally. This release includes a built-from-scratch Tag that is able to represent all types required to express Kyo computations and effects including variance support. The kernel has been changed to support effects with variance but the current effect implementations still use erased tags, pending migration. If you're curious about algebraic effects and their relation to delimited continuations, this test should be an interesting reading (by @fwbrasil in #1171, #1181)
Stream improvements: Streams remain a major focus of the project towards Kyo 1.0. In this release, new APIs were added: concurrent stream merging via Stream.collectAll and stream.merge, parallel stream transformation via stream.mapPar and stream.mapChunkPar, lazily evaluated stream sources via Stream.repeatPresent, and stateful stream sources via Stream.unfoldKyo. We're not expecting major API changes to Stream itself but we're exploring optimizations and still extending its API. (by @johnhungerford in #1123, #1156, @vladpo in #1139, and @HollandDM in #1164)
Sink: Stream used to provide a few methods for execution but their functionality was limited. Sink extends the functionality of Stream by providing convenient stream handling logic. Like Stream is backed by the Emit effect in kyo-prelude, Sink is its dual based on Poll. Sink provides several stream consumption strategies and can be composed with other sinks. (by @johnhungerford in #1157)
Karray: The new KArray type in kyo-data is an alternative to IArray with optimized methods to avoid allocations and function dispatch overhead. Methods like exists and forall have performance equivalent to hand-written while loops and avoid boxing via inlining. This new data structure was an important optimization in the new Tag implementation, enabling zero-allocation sub-type checking. (by @fwbrasil in #1180)
More flexible effect handling: The kernel has been improved to provide more control to effect handler implementations. Previously, support for introducing new effect suspensions during the handling of an effect was limited to handleState, which required handlers to use it even without the need for state. ArrowEffect now provides a new set of handleLoop methods following the API pattern of the Loop effect and providing more fine-grained control over effect handling including the abilities to perform new effect suspensions and to stop effect handling. (by @fwbrasil in #1150)
Generic collection methods: The collection handling methods in the Kyo companion objects aren't restricted to Seq anymore and now accept IterableOnce. (by @HollandDM in #1149)
Support for Text in Log: The Log API now supports Text in addition to String. (by @hearnadam in #1163)
Time-slice preemption in JS: The JS scheduler used to be a simple delegate to the JS runtime without handling preemption, which required explicit yields. This release introduces time-based preemption like in the JVM. (by @fwbrasil in #1145)
More flexible resource handling: We're planning a major change to the Resource effect before 1.0-RC1. As a preparation, the effect was changed to enable abstraction of finalizers. (by @hearnadam in #1137)
Value return in Loop.foreach: The API now supports returning a final value via Loop.done. (by @hearnadam in #1160)
Choice.runStream: The Choice effect can now stream results as they become available. This can be useful when the Choice effect is used to evaluate multiple options with different depths of rejection and completion. (by @fwbrasil in #1182)
Optimizations
Chunk: Commonly used Chunk methods were specialized to provide efficient execution without the overhead of the default Scala collection methods. In addition, chunks of a single item now have a specialized internal representation to reduce allocations. (by @fwbrasil in #1184, @HollandDM in #1142)
Resource: The effect handling now avoids unnecessary computations when the scope has no resources to close. (by @fwbrasil in #1144)
Fixes
Abort in STM: The STM effect wasn't retrying transactions in case of Abort suspensions due to inconsistent STM reads. This behavior has been fixed to automatically retry aborts when the transaction isn't consistent, even if it doesn't reach the commit phase. (by @fwbrasil in #1169)
NPE in trace enriching: The logic to insert Kyo traces in stack traces could throw an NPE, which has been fixed. (by @hearnadam in #1174)
Fix Promise variance: The encoding of Promise had an issue with variance, which enabled completing the promise with an incorrect type. (by @fwbrasil in #1143)
Breaking changes
Monix removal: The integration with Monix has been removed in this release due to maintenance challenges. (by @fwbrasil in #1147)
New Contributors
Full Changelog: v0.18.0...v0.19.0
v0.18.0
Kyo 0.18.0
New Features
-
Actors: The new
kyo-actormodule introduces type-safe actors built on top of other effects likeChannelandPoll. The API enables composition with other effects both within an actor implementation and in itsActor.runcreation scope. For example, actors can requireEnvvalues in their initialization or leverageRetryandAbortto compose supervision strategies in their bodies. This initial version includes local actors only, but theSubjectabstraction is designed to enable remote communication. The goal is eventually integrating the module withkyo-aeronfor distributed actors. This work was based on a collaboration with @DamianReeves. Thank you! (by @fwbrasil in #1107) -
Abort with literals: The
Aborteffect now supports short-circuiting computations with a literal value for situations where creating a new type for aborting isn't convenient. For instance,Abort.literal.fail["invalid"]will provide a computation with a pendingAbort["invalid"]that can be handled viaAbort.literal.run. (by @hearnadam in #1118) -
Playwright browser integration: The
kyo-playwrightmodule provides a new Browser effect for programmatic browsing with support for several features like screenshotting, mouse usage, and extracting readable content. The effect also provides a low-level API viaBrowser.Opclasses designed to enable LLM interaction via tools. (by @fwbrasil in #1113)
Improvements
-
Async.fillIndexedmethod to repeat a computation multiple times with their indexes. (by @fwbrasil in #1110) -
Stream.splitAtmethod to take a specific number of elements out of a stream and return it with a new stream with the remaining emissions. (by @HollandDM in #1092) -
Var.updateWithmethod to enable updating a var and performing a transformation in a single allocation. (by @fwbrasil in #1135) -
Scaladocs in
kyo-corewere reviewed and improved to better document the motivation of effects and their behaviors. (by @fwbrasil in #1104) -
The repository now has a CONTRIBUTING.md with general information on how to contribute. (by @c0d33ngr in #1112)
-
The
kyo-combinatorsmodule had a major refactoring, reorganizing the code into multiple files and making the APIs and implementations more consistent with the rest of the codebase. (by @johnhungerford in #1102) -
We're starting to explore providing first-class support for Java in the
kyo-schedulermodules. As a first step, we've validated that the current APIs are usable from Java. (by @hearnadam in #1121) -
Most of Kyo's classes were marked as
Serializable, enabling support for Java serialization of computations. The main exception isFibers and classes that hold references to them since persisting the state of a running fiber would produce inconsistent behaviors. (by @fwbrasil in #1132)
Fixes
-
Channelhad an edge case with zero capacity where the behavior wasn't well defined. This version includes a new implementation with proper support for zero-capacity channels. (by @johnhungerford in #1108) -
Pathhad an encoding issue in Windows that has been fixed. (by @ffilipus in #1109) -
A memory leak related to a single fiber handling multiple parking operations and their interruptions was fixed. (by @fwbrasil in #1125)
Breaking Changes
-
The
pipemethod in the pending type (<) has been renamed tohandleto better indicate that the API is meant primarily for effect handling even though it still supports arbitrary transformations. (by @fwbrasil in #1115) -
The project used to use a pattern with
Opsclasses to enable multiple type parameter groups. These were now migrated to the new clause interleaving language feature. This change improves usability with the newly namedhandlemethod with effect handlers. (by @fwbrasil in #1114) -
Var.setAndThenhas been renamed toVar.setWithto follow the new naming pattern in the codebase whereWithindicates that the operation takes a continuation function. (by @fwbrasil in #1133)
New Contributors
Full Changelog: v0.17.0...v0.18.0
v0.17.0
This is likely one of the last releases before the 1.0-RC cycle! Please report any issues or difficulties with the library so we can address them before committing to a stable API 🙏
Also, Kyo has a new logo! Thank you @Revod!!! (#1105)
New features
-
Reactive Signal: A new Signal implementation has been introduced in
kyo-core, inspired by fs2. Signals can change value over time and these changes can be listened for via the methods that integrate withStream. (by @fwbrasil in #1082) -
Consistent collection operations: Handling collections with the
Kyocompanion object is very flexible, while doing the same withAsyncused to be less convenient and with a completely different API approach. In this release, a new set of methods to handle collections was added to the Async effect, mirroring the naming of theKyocompanion. With this, most collection operations can either useKyofor sequential processing orAsyncfor concurrent/parallel processing. (by @fwbrasil in #1086) -
Partial error handling: The
Aborteffect had a limitation that doesn't allow the user to handle only expected failures without panics (unexpected failures). This release introduces APIs to handle aborts without panics in the Abort.*Partial methods. Similarly, a new Result.Partial type was introduced to represent results without panics. (by @johnhungerford in #1042) -
Record staging: Records can now be materialized from a type signature using a function to populate the values. This feature is meant to enable the creation of DSLs. For example, given a record type
"name" ~ String & "age" ~ Int, it's possible to stage it for a SQL DSL as"name" ~ Column[String] & "age" ~ Column[Int]. (by @road21 in #1094) -
Aeron integration: The new Topic effect in the
kyo-aeronmodule provides a seamless way to leverage Aeron's high-performance transport with support for both in-memory IPC and reliable UDP. Stream IDs are automatically derived from type tags, providing typed communication channels, and serialization is handled via upickle. (by @fwbrasil in #1048) -
Direct Memory in Scala Native: The Memory effect provides direct memory access with automatic handling of resources via scoping. The module now also has support for Scala Native! (by @akhilender-bongirwar in #1072)
Improvements
-
Unified Isolate mechanism: In this release, two mechanisms used to provide support for effects with forking,
IsolateandBoundary, were merged into a single implementation with better usability.Isolate.Contextualprovides isolation for contextual effects likeEnvandLocal, whileIsolate.Statefulis a more powerful mechanism that is able to propagate state with forking and restore it. A few effects provide defaultIsolateinstances but not all. For example, given the problematic semantics of mutable state in the presence of parallelism,Vardoesn't provide anIsolateevidence, which disallows its use with forking by default and requires explicit activation (seeVar.isolate.*). (by @fwbrasil in #1077) -
More convenient discarding methods: Methods that execute a provided function but don't use its result used to require functions to return
Unit. In this release, methods were changed to acceptAnyas the result of the function. For example, theunitcall inResource.ensure(queue.close.unit)can now be omitted:Resource.ensure(queue.close). (by @johnhungerford in #1070) -
Less verbose errors: Kyo logs rich failures including a snippet of the failing code for a better development experience. This behavior is problematic in production systems due to the verbosity. A new Environment mechanism was introduced to detect if Kyo is executing in a development mode and disable the rich failure rendering if not. The detection mechanism currently only supports SBT, but the user can enable the development mode via a system property. (by @fwbrasil in #1057)
-
Better resource handling in Hub: The
initmethods ofHubweren't attaching a finalizer via theResourceeffect. This has been fixed in this release. (by @johnhungerford in #1066) -
Remove IOException from Console APIs: The
Consolemethods used to indicate that the operation could fail withAbort[IOException], but that was an incorrect assumption. The underlying Java implementation doesn't throw exceptions and a separate method is provided to check for errors. Kyo now reflects this behavior by not trackingAbort[IOException]and providing a newConsole.checkErrorsmethod. (by @rcardin in #1069) -
Multi-get Env APIs: The new Env.getAll/useAll methods enable getting multiple values from the environment at once. For example:
Env.getAll[DB & Cache & Config], which returns aTypeMap[DB & Cache & Config]. (by @fwbrasil in #1099) -
Rename
runprefix in Stream: Some of the methods inStreamwere prefixed withrunto indicate that they will evaluate the stream, which wasn't very intuitive. The prefix was removed and, for example,Stream.runForeachis nowStream.foreach. (by @c0d33ngr in #1062) -
Non-effectful Stream methods: The methods in the Stream class were designed to assume that all operations are effectful, which introduces overhead due to the unnecessary effect handling when the function is effect-free. This release includes overloaded versions of methods, which allows the compiler to select the non-effectful version if possible. Benchmark results show a major improvement. (by @johnhungerford in #1045)
-
Maybe.collect optimization: The method has been updated to use
applyOrElse, which avoids the need to call the partial function twice. (by @matteobilardi in #1083) -
Path.readAll fix: The method wasn't returning the correct file names. (by @hearnadam in #1090)
New Contributors 👏
- @rcardin made their first contribution in #1069
- @matteobilardi made their first contribution in #1083
- @akhilender-bongirwar made their first contribution in #1072
- @Revod made their first contribution in #942
Full Changelog: v0.16.2...v0.17.0
v0.16.2
What's Changed
- [data] records more than 22 AsFields (#1006) by @road21 in #1013
- [stm] fix TTable index initialization by @fwbrasil in #1012
- core: exit KyoApp on failure by @hearnadam in #1031
- remove IO.unit by @fwbrasil in #1041
- [core] Fix SLF4J log levels by @hearnadam in #1046
There are a few new features that will be announced with 0.17.0.
Full Changelog: v0.16.1...v0.16.2
Kyo 0.16.1
This release (0.16.1) temporarily disables the Scheduler's Singleton mechanism: #1011.
New Features
-
Scheduler integrations for Finagle and cats-effect: We've been observing positive results with
kyo-scheduler-zioenabled for ZIO apps and this new version introduces integrations for both Finagle and cats-effect. For cats-effect, the integration enables replacing the defaultWorkStealingThreadPoolwith Kyo's high-performance work-stealing adaptive scheduler via KyoSchedulerIOApp or KyoSchedulerIORuntime. Admission control needs to be manually wired like in ZIO's integration. For Finagle, the integration uses extension points in Finagle'sFinagleSchedulerServiceandForkingScheduler, redirecting allFuturePoolworkload to Kyo's scheduler and automatically wiring the admission control in the server stack. The new module only needs to be in the classpath and Finagle locates it via service loading. These integrations should provide improved peak performance and scalability, especially in environments with CPU quotas due to the scheduler's CPU throttling mitigation via adaptive concurrency. These integration modules are isolated and don't include dependencies on the effect system. -
Stream improvements and integrations: As mentioned in the last release, improving Streams is a key effort for Kyo 1.0. This release includes an integration with Reactive Streams and Java's Flow, the ability to stream values from a channel and from Hub listeners, new tap and tapChunk methods, and extensions to read and write gzip compressed data.
-
Batched Channel operations: Both reads and writes to channels now support batching, reducing the coordination overhead to exchange values between fibers. Additionally, the new drainUpTo method enables taking values immediately available in the channel without parking while properly considering pending puts.
-
Records:
kyo-data, an isolated module without a dependency on the effect system, now offers an implementation of records based on intersection types to track available fields and types. The encoding enables type-level constraints, for example restricting what fields can be used in specific APIs, provides a proper sub-type relationship between records, automatic derivation from case classes, and convenient type-safe field access. -
STM: TChunk, TSchedule, and TTable: The
kyo-stmmodule now includes transactional versions of Chunk, Schedule, and a new record-based TTable, which offers a convenient API to store and query records with indexing support. The module also received some new optimizations. -
Render type class: A new type class for rendering text representations of values was introduced in
kyo-dataand implementations for common Kyo types were introduced. This is an important aspect for usability given Kyo's extensive use of opaque types, which can lose fidelity when transformed via the regulartoString. -
Async.memoize and Async.never: Two new async combinators that respectively provide memoization of async computations and producing a computation that never completes.
-
Improved direct syntax: The direct syntax now provies extension methods .now and .later instead of
await, which provides a more lightweight syntax. The.laterextension is designed as an advanced API to enable composition of lazy effectful computations withindeferblocks. In addition, the module was restructured to provide more informative compile-time error reporting. -
Anchored and Jittered Schedules: The
Scheduleimplementation inkyo-datanow offers a Schedule.anchored constructor for cron-like schedules and a jitter method to introduce schedule duration variation. The STM module now uses a jittered retry schedule to reduce the impact of retry storms. -
Emit and orDie combinators: The
kyo-combinatorsmodule, which offers ZIO-like APIs, now includes extensions for the Emit effect and a new orDie combinator.
Improvements
-
IO now includes Abort[Nothing]: The
IOeffect now includes handling of unexpected panics viaAbort[Nothing]. Computations that previously hadIO & Abort[Nothing]in the pending set now can only includeIO. -
IOPromise improvements:
IOPromise, the underlying implementation ofFiber, was fixed to ensure proper handling of non-fatal exceptions in callbacks and an optimization was implemented to avoid a nested AtomicReference allocation. -
Async as a super set of IO: A new Async.apply method was introduced to provide side-effect suspension and enable using
Asyncas a super set ofIOin most scenarios.IO, the effect for side-effect suspension, andAsync, the effect for handling asynchronous boundaries, had scaladocs improved to better explain the difference between these effects. For most users, usingAsyncdirectly is recommended to reduce the effect tracking overhead. -
KyoApp in JS: The implementation was fixed to avoid thread blocking so ScalaJS is properly supported.
-
New kyo-kernel module: The kernel of the library is now isolated from all effect implementations. Additionally, the module was restructured and its scaladoc documentation is improved.
-
Better exceptions: Exceptions for Kyo's APIs now extend a common KyoException base type, which provides better error reporting via Frame.
-
Chunk improvements: The implementation was optimized by extending
StrictOptimizedSeqOpsand providing more efficientiterator,take,appendedmethods. Additionally, more methods now return aChunkinstead ofSeqfor better usability and a bug in the implementation was fixed. -
Scheduler improvements: Task preemption is now avoided in case the worker doesn't have other pending workload, parameters were tuned to provide a behavior similar to cats-effect's default scheduler, the distribution of the random number generation used for scheduling decisions was improved, and a mechanism was introduced to ensure Kyo's scheduler is a singleton even in the presence of multiple class loaders.
Breaking Changes
-
More clear method naming: The methods provided by
Consolenow use more explicit naming by spellingLineinstead ofln, atomic classes now providecompareAndSetinstead of the shortenedcas,Emit.applywas replaced byEmit.value, andCheck.applywas replaced byCheck.require. -
Removed STM's initNow: The implementation in the STM module used to offer
initandinitNowto distinguish between transactional and non-transactional instantiation. This release removes allinitNowmethods and changesinitto dynamically select transactional or non-transactional instantiation depending on the presence of an outer `STM.run...
v0.16.0
Kyo 0.16.0
New Features
-
Scheduler integrations for Finagle and cats-effect: We've been observing positive results with
kyo-scheduler-zioenabled for ZIO apps and this new version introduces integrations for both Finagle and cats-effect. For cats-effect, the integration enables replacing the defaultWorkStealingThreadPoolwith Kyo's high-performance work-stealing adaptive scheduler via KyoSchedulerIOApp or KyoSchedulerIORuntime. Admission control needs to be manually wired like in ZIO's integration. For Finagle, the integration uses extension points in Finagle'sFinagleSchedulerServiceandForkingScheduler, redirecting allFuturePoolworkload to Kyo's scheduler and automatically wiring the admission control in the server stack. The new module only needs to be in the classpath and Finagle locates it via service loading. These integrations should provide improved peak performance and scalability, especially in environments with CPU quotas due to the scheduler's CPU throttling mitigation via adaptive concurrency. These integration modules are isolated and don't include dependencies on the effect system. -
Stream improvements and integrations: As mentioned in the last release, improving Streams is a key effort for Kyo 1.0. This release includes an integration with Reactive Streams and Java's Flow, the ability to stream values from a channel and from Hub listeners, new tap and tapChunk methods, and extensions to read and write gzip compressed data.
-
Batched Channel operations: Both reads and writes to channels now support batching, reducing the coordination overhead to exchange values between fibers. Additionally, the new drainUpTo method enables taking values immediately available in the channel without parking while properly considering pending puts.
-
Records:
kyo-data, an isolated module without a dependency on the effect system, now offers an implementation of records based on intersection types to track available fields and types. The encoding enables type-level constraints, for example restricting what fields can be used in specific APIs, provides a proper sub-type relationship between records, automatic derivation from case classes, and convenient type-safe field access. -
STM: TChunk, TSchedule, and TTable: The
kyo-stmmodule now includes transactional versions of Chunk, Schedule, and a new record-based TTable, which offers a convenient API to store and query records with indexing support. The module also received some new optimizations. -
Render type class: A new type class for rendering text representations of values was introduced in
kyo-dataand implementations for common Kyo types were introduced. This is an important aspect for usability given Kyo's extensive use of opaque types, which can lose fidelity when transformed via the regulartoString. -
Async.memoize and Async.never: Two new async combinators that respectively provide memoization of async computations and producing a computation that never completes.
-
Improved direct syntax: The direct syntax now provies extension methods .now and .later instead of
await, which provides a more lightweight syntax. The.laterextension is designed as an advanced API to enable composition of lazy effectful computations withindeferblocks. In addition, the module was restructured to provide more informative compile-time error reporting. -
Anchored and Jittered Schedules: The
Scheduleimplementation inkyo-datanow offers a Schedule.anchored constructor for cron-like schedules and a jitter method to introduce schedule duration variation. The STM module now uses a jittered retry schedule to reduce the impact of retry storms. -
Emit and orDie combinators: The
kyo-combinatorsmodule, which offers ZIO-like APIs, now includes extensions for the Emit effect and a new orDie combinator.
Improvements
-
IO now includes Abort[Nothing]: The
IOeffect now includes handling of unexpected panics viaAbort[Nothing]. Computations that previously hadIO & Abort[Nothing]in the pending set now can only includeIO. -
IOPromise improvements:
IOPromise, the underlying implementation ofFiber, was fixed to ensure proper handling of non-fatal exceptions in callbacks and an optimization was implemented to avoid a nested AtomicReference allocation. -
Async as a super set of IO: A new Async.apply method was introduced to provide side-effect suspension and enable using
Asyncas a super set ofIOin most scenarios.IO, the effect for side-effect suspension, andAsync, the effect for handling asynchronous boundaries, had scaladocs improved to better explain the difference between these effects. For most users, usingAsyncdirectly is recommended to reduce the effect tracking overhead. -
KyoApp in JS: The implementation was fixed to avoid thread blocking so ScalaJS is properly supported.
-
New kyo-kernel module: The kernel of the library is now isolated from all effect implementations. Additionally, the module was restructured and its scaladoc documentation is improved.
-
Better exceptions: Exceptions for Kyo's APIs now extend a common KyoException base type, which provides better error reporting via Frame.
-
Chunk improvements: The implementation was optimized by extending
StrictOptimizedSeqOpsand providing more efficientiterator,take,appendedmethods. Additionally, more methods now return aChunkinstead ofSeqfor better usability and a bug in the implementation was fixed. -
Scheduler improvements: Task preemption is now avoided in case the worker doesn't have other pending workload, parameters were tuned to provide a behavior similar to cats-effect's default scheduler, the distribution of the random number generation used for scheduling decisions was improved, and a mechanism was introduced to ensure Kyo's scheduler is a singleton even in the presence of multiple class loaders.
Breaking Changes
-
More clear method naming: The methods provided by
Consolenow use more explicit naming by spellingLineinstead ofln, atomic classes now providecompareAndSetinstead of the shortenedcas,Emit.applywas replaced byEmit.value, andCheck.applywas replaced byCheck.require. -
Removed STM's initNow: The implementation in the STM module used to offer
initandinitNowto distinguish between transactional and non-transactional instantiation. This release removes allinitNowmethods and changesinitto dynamically select transactional or non-transactional instantiation depending on the presence of an outerSTM.runtransaction. -
Adopt With naming pattern: Methods that take a continuation function now use the
With...
v0.15.1
What's Changed
- [monix] scaladocs by @fwbrasil in #899
- [stm] fix race condition during commit + enable Native by @fwbrasil in #901
- [data][prelude][core] Poll effect + handleFirst by @fwbrasil in #891
- [readme][build] make unused value warnings a compilation error by @fwbrasil in #905
Full Changelog: v0.15.0...v0.15.1
v0.15.0
This is yet another packed #Kyo release! ✨
-
Monix Integration: The new kyo-monix module implements integration with Monix's
Task, similar tokyo-zioandkyo-cats. -
Multithreaded Scala Native: Support for Scala Native has been expanded to
kyo-scheduler,kyo-core,kyo-direct,kyo-sttp, andkyo-combinators. Kyo's adaptive scheduler and high-performance async primitives can now be used in Native! -
STM Effect: A new STM effect is available in the
kyo-stmmodule, including a TMap data structure. The implementation uses a fine-grained read/write commit-time lock mechanism designed to reduce retry likelihood and allow transactions to commit concurrently in more scenarios. -
Stream Improvements: Improving streams is a key effort toward Kyo 1.0. This release makes streams lazier and introduces a new Stream.rechunk API.
-
Async.gather: New async operators to execute multiple computations in parallel and gather successful results. The APIs allow specifying a maximum number of computations to wait for. Once gathering is complete, all remaining pending fibers are automatically interrupted.
-
Effect Isolates: A new mechanism in
kyo-preludeproviding MTL-like state isolation with rollback capabilities. Integrates withAsyncAPIs and powers theSTMeffect's retry handling. -
Scheduler Improvements: The scheduler module now includes scaladocs clarifying its implementation and design decisions. Additionally, the scheduler's Admission Control mechanism is now exposed as a user-facing API in
kyo-core. -
Batch Effect Simplification: The Batch effect has been enhanced to provide the same functionality without requiring the type parameter previously used to track effects from sources.
-
Gen and Check Support in kyo-test:
kyo-testnow provides a stronger integration withzio-test, enabling users to mix zio/kyo effects in the same test suite. This unlocks the use ofGenandcheck. -
Chunk Builder: Chunk now provides a collection builder API for better integration with Scala Collections.
Full Changelog: v0.14.1...v0.15.0