Skip to content

Mosaic 0.6.0

Choose a tag to compare

@github-actions github-actions released this 03 Oct 22:59
· 21 commits to main since this release
b193662

Mosaic 0.6.0 release notes

Mosaic 0.6.0 brings named Tiles and execution tracing to a shared runtime with
Mosaic-owned Canvas construction and resource ownership.

Canvas and execution

Canvas is now a final Mosaic-owned class, created through canvas and
withLayer. It holds resolved bindings and inherited runtime configuration;
each Mosaic owns its request cache, batching, and execution state. mosaic-test
uses that same runtime with substituted Tiles and a test dispatcher.

Ordinary request layers that bind values stay small:

applicationCanvas.withLayer {
  single(OrderKey) { orderId }
}.create().compose(OrderPageTile)

Scope or close a Canvas when its local bindings own AutoCloseable resources.
Closing a child leaves parent resources open. Construction shares concurrent
binding resolution, detects dependency cycles, and cleans up successfully created
local resources on failure or cancellation in reverse creation order.

Named Tiles and observation

Use val OrderTile by singleTile { ... } to capture a property name. The same
syntax works with multiTile, perKeyTile, and chunkedMultiTile. Aliases retain
the first bound name and the original Tile instance; names do not change caching.
Ordinary = declarations remain valid and initially have no name.

The new mosaic-opentelemetry module adds
spans to your application's OpenTelemetry pipeline:

val applicationCanvas = canvas {
  tracing { openTelemetry }
}

Use tracing() with an already registered global provider, including a Java agent.
Spans use delegated Tile names when available, otherwise Mosaic single or
Mosaic multi. Shared work and additional batch callers appear as links; cache
hits create no spans. Context survives suspension and dispatcher changes.
Execution spans include attached child coroutines, even when a result is available
earlier. Observation failures are isolated from Tile results; each Mosaic retains
ownership of its shared work, caching, and batching.
Your application owns the SDK, sampling, exporters, and shutdown. Automatic
telemetry excludes keys, values, request identifiers, and exception contents;
delegated property names are visible as span names.

The runtime BOM now aligns mosaic-core, mosaic-test, and the optional adapter.
Adding the BOM alone does not install tracing.

Compatibility and migration

  • Canvas source and binary break: external implementations, inheritance, and
    delegation of the former Canvas interface are unsupported. MosaicCanvas is
    removed. Replace direct implementation/construction with canvas or withLayer,
    and recompile consumers against 0.6.0. CanvasBuilder/CanvasFactory construction
    belongs to Mosaic; use the public DSL.
  • Kotlin: built with compiler and Gradle plugin 2.4.20, language/API level
    2.4, stdlib 2.4.20, and coroutines 1.11.0. Runtime artifacts are tested
    with Kotlin 2.3.0 consumers. Java 17 remains the runtime minimum; repository
    builds and framework examples use JDK 21 and Gradle 8.14.4.
  • Analysis: requires exactly Kotlin compiler and Gradle plugin 2.4.20.
    Rebuild dependency summaries generated with other compiler versions. Supported
    Mosaic-owned delegated declarations preserve contracts; arbitrary delegates and
    member-dependent Tile properties remain conservative analysis boundaries.
  • Delegate operators: Mosaic's member provideDelegate/getValue operators
    take precedence over custom extension operators when consumers recompile.
  • OpenTelemetry: the adapter exposes API 1.66.0 and includes core. It does
    not install an SDK or the optional Kotlin context extension in your application.

Runtime cost

A targeted JMH comparison with released 0.5.0, with tracing disabled, measured
the following synthetic runtime operations:

Operation 0.5.0 µs/op 0.6.0 µs/op
Four-branch shared diamond 5.6 5.7
Four sibling coalescing consumers 7.8 8.0
64-Tile chain 27.7–28.4 28.9

Across comparison orders, the remaining timing differences were about
0.09–0.15 µs/op for diamond, 0.16 µs/op for sibling coalescing, and
0.6–1.2 µs/op for the 64-Tile chain. The diamond and coalescing fixtures
allocated about 1.2 KB/op and 1.6–1.9 KB/op more, respectively.
Cold trivial Tiles and cold 16-key batches had overlapping timing intervals.
Cost depends on graph shape; the technical guide includes width, depth, cache,
and complete execution-drain measurements.

These are elapsed microbenchmark timings, not application CPU/request or HTTP
latency. Timing and allocation were measured separately on JDK 21; reversed
comparison order confirmed the graph differences. See the
comparison methodology and results.
The application performance results describe their
documented source revision and were not remeasured for 0.6.0.

See the core guide,
analysis setup, and
changelog for usage and the complete release summary.

[0.6.0] - 2026-10-03

Added

  • Delegated Tile naming with val OrderTile by singleTile { ... } and equivalent
    MultiTile factories. Aliases preserve the first name and the same cache identity.
  • Supported execution observation for actual Tile executions and MultiTile batches,
    including caller context, shared-work relationships, and sanitized completion.
    Observation failures are isolated from Tile results.
  • Optional mosaic-opentelemetry module and Canvas tracing() / tracing { openTelemetry }
    DSL. Spans use delegated Tile names, propagate coroutine context, and link shared work.
    The runtime BOM aligns the adapter alongside core and test libraries.

Changed

  • Canvas is a final Mosaic-owned class built with canvas or withLayer.
    External Canvas implementations and MosaicCanvas are removed; migrate to the DSL.
  • Canvas construction shares concurrent dependency resolution, detects cycles, and
    cleans up local resources on failure/cancellation in reverse creation order.
  • Kotlin compiler and Gradle plugin move to 2.4.20 with language/API level 2.4;
    runtime dependencies use stdlib 2.4.20 and coroutines 1.11.0. Runtime consumers
    require Kotlin 2.3.0 or later; JVM 17 remains the runtime target.
  • Optional analysis supports exactly Kotlin compiler/Gradle plugin 2.4.20 and
    recognizes supported Mosaic-owned delegated Tile declarations. Older compiler
    summaries must be regenerated.