From 6c8e44c22f26f849a684079a8255aa172d4e45ba Mon Sep 17 00:00:00 2001 From: darkryh Date: Wed, 26 Aug 2026 16:26:38 -0500 Subject: [PATCH] chore(release): cut 1.0.0-beta04 Version pins move together, as in fd9c836: gradle.properties (which is what release-library.yml publishes), the README and docs snippets, the initializr default, and the sample + consumer-smoke consumer builds. What this release carries: - Katalyst has a shutdown lifecycle. It had StartupHook and ReadyHook and nothing on the way down, so it closed the connection pool with application background work still running - the polling loops and consumers ReadyHook's own KDoc invites. Every such shutdown ended in SQLSTATE 08006 / Socket closed followed by "No transaction manager for db ExposedDatabase[...]". ShutdownHook is the missing half, and it SUSPENDS: Katalyst awaits it, so a worker can cancelAndJoin and be genuinely finished before anything is taken away. Ktor's ApplicationStopping subscribers are synchronous and can only ever signal a worker, never join it. - Katalyst now tears down on ApplicationStopped rather than ApplicationStopping. It subscribes before start() while an application's KtorModules subscribe during it, so it was always first in the handler list and the documented, Ktor-native way to stop a worker was guaranteed to run too late. Applications using that idiom are fixed without changing a line. - The connection pool is given a bounded moment to go quiet before it closes, covering work that was cancelled but not joined. If it expires, a WARN names how many connections are still checked out - which is the signal that some background work needs a ShutdownHook. - KatalystFeature gains onShutdown(context), the same gap one level up. - LifecycleHook now carries id/order for StartupHook, ReadyHook and ShutdownHook. Each declared its own defaults before, so the most ordinary shape in the framework - one class that starts a worker and stops it again - had to override both for no reason. Source-compatible; binary-breaking for already-compiled hook implementors, which is acceptable pre-1.0. The defect was present since at least alpha10 and is not a beta03 regression - verified by reproducing it identically on beta02 and beta03. Validated on this commit: full `check`, `apiCheck`, `koverVerify`, `samples/validate-samples.sh`, and consumer-smoke across netty/jetty/cio. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 2 +- docs/getting-started.md | 2 +- docs/how-to/test-applications.md | 2 +- docs/reference/modules.md | 6 +++--- gradle.properties | 2 +- harness/consumer-smoke/build.gradle.kts | 4 ++-- samples/katalyst-example/build.gradle.kts | 6 +++--- web/initializr/build.gradle.kts | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1bd5fd5..37615d9 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ repositories { } dependencies { - val katalyst = "1.0.0-beta03" // latest version — see the Maven Central badge above + val katalyst = "1.0.0-beta04" // latest version — see the Maven Central badge above implementation(platform("io.github.darkryh.katalyst:katalyst-bom:$katalyst")) implementation("io.github.darkryh.katalyst:katalyst-starter-web") diff --git a/docs/getting-started.md b/docs/getting-started.md index 2f1b0d5..aba4d31 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -39,7 +39,7 @@ plugins { repositories { mavenCentral() } dependencies { - val katalyst = "1.0.0-beta03" + val katalyst = "1.0.0-beta04" implementation(platform("io.github.darkryh.katalyst:katalyst-bom:$katalyst")) implementation("io.github.darkryh.katalyst:katalyst-starter-web") implementation("io.github.darkryh.katalyst:katalyst-starter-engine-netty") diff --git a/docs/how-to/test-applications.md b/docs/how-to/test-applications.md index 079bae8..dd500e0 100644 --- a/docs/how-to/test-applications.md +++ b/docs/how-to/test-applications.md @@ -11,7 +11,7 @@ declare for the main dependencies, so add the BOM to the test configuration too starter's version: ```kotlin -testImplementation(platform("io.github.darkryh.katalyst:katalyst-bom:1.0.0-beta03")) +testImplementation(platform("io.github.darkryh.katalyst:katalyst-bom:1.0.0-beta04")) testImplementation("io.github.darkryh.katalyst:katalyst-starter-test") ``` diff --git a/docs/reference/modules.md b/docs/reference/modules.md index b3cd895..a1a5b83 100644 --- a/docs/reference/modules.md +++ b/docs/reference/modules.md @@ -2,11 +2,11 @@ Katalyst is published as a set of focused modules under the group `io.github.darkryh.katalyst`. Depend only on what you use. All modules share the same -version (current line: `1.0.0-beta03`). Applications should consume the BOM and feature +version (current line: `1.0.0-beta04`). Applications should consume the BOM and feature starters; the lower-level modules below remain useful for advanced integrations. ```kotlin -val katalyst = "1.0.0-beta03" +val katalyst = "1.0.0-beta04" implementation(platform("io.github.darkryh.katalyst:katalyst-bom:$katalyst")) implementation("io.github.darkryh.katalyst:katalyst-starter-web") implementation("io.github.darkryh.katalyst:katalyst-starter-engine-netty") @@ -96,7 +96,7 @@ Pull all three in at once with the `katalyst-starter-observability` starter. A full-featured service usually pulls in: ```kotlin -val katalyst = "1.0.0-beta03" +val katalyst = "1.0.0-beta04" implementation(platform("io.github.darkryh.katalyst:katalyst-bom:$katalyst")) implementation("io.github.darkryh.katalyst:katalyst-starter-web") implementation("io.github.darkryh.katalyst:katalyst-starter-engine-netty") diff --git a/gradle.properties b/gradle.properties index 1e07c64..8b87b9c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official katalystGroup=io.github.darkryh.katalyst -katalystVersion=1.0.0-beta03 +katalystVersion=1.0.0-beta04 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/harness/consumer-smoke/build.gradle.kts b/harness/consumer-smoke/build.gradle.kts index b394203..8168fa9 100644 --- a/harness/consumer-smoke/build.gradle.kts +++ b/harness/consumer-smoke/build.gradle.kts @@ -5,7 +5,7 @@ import org.gradle.api.tasks.testing.Test plugins { // The ONLY plugin a Katalyst consumer applies. It pulls in Kotlin JVM, kotlinx.serialization // and the application plugin. Resolving it here proves the published plugin marker works. - id("io.github.darkryh.katalyst") version "1.0.0-beta03" + id("io.github.darkryh.katalyst") version "1.0.0-beta04" } group = "com.example" @@ -29,7 +29,7 @@ sourceSets.named("main").configure { // CRITICAL: not a single Ktor or Exposed coordinate appears here. Both arrive transitively through // the katalyst-* starters — that is the property this harness exists to prove. dependencies { - val katalyst = "1.0.0-beta03" + val katalyst = "1.0.0-beta04" implementation(platform("io.github.darkryh.katalyst:katalyst-bom:$katalyst")) implementation("io.github.darkryh.katalyst:katalyst-starter-web") implementation("io.github.darkryh.katalyst:katalyst-starter-persistence") diff --git a/samples/katalyst-example/build.gradle.kts b/samples/katalyst-example/build.gradle.kts index 2feddd0..c2d3f14 100644 --- a/samples/katalyst-example/build.gradle.kts +++ b/samples/katalyst-example/build.gradle.kts @@ -1,8 +1,8 @@ plugins { // The single Katalyst plugin applies Kotlin JVM, kotlinx.serialization and the application // plugin. No version: it is resolved from the composite build (see settings.gradle.kts). - // A published consumer would write: id("io.github.darkryh.katalyst") version "1.0.0-beta03" - id("io.github.darkryh.katalyst") version "1.0.0-beta03" + // A published consumer would write: id("io.github.darkryh.katalyst") version "1.0.0-beta04" + id("io.github.darkryh.katalyst") version "1.0.0-beta04" } group = "io.github.darkryh" @@ -13,7 +13,7 @@ application { mainClass = "io.github.darkryh.katalyst.example.ApplicationKt" } // Only katalyst-* artifacts — Ktor, Exposed, Koin, serialization, etc. all arrive transitively // through the starters. Pick the server engine by adding exactly one katalyst-starter-engine-*. dependencies { - val katalyst = "1.0.0-beta03" + val katalyst = "1.0.0-beta04" implementation(platform("io.github.darkryh.katalyst:katalyst-bom:$katalyst")) implementation("io.github.darkryh.katalyst:katalyst-starter-web") implementation("io.github.darkryh.katalyst:katalyst-starter-engine-netty") diff --git a/web/initializr/build.gradle.kts b/web/initializr/build.gradle.kts index 1cfa3fa..976a6f2 100644 --- a/web/initializr/build.gradle.kts +++ b/web/initializr/build.gradle.kts @@ -14,7 +14,7 @@ version = "1.0.0-SNAPSHOT" // so the published site tracks whatever release was just cut — alpha, beta, rc or stable. Falls back // to the current line for local and non-release builds. val katalystVersion: String = - (findProperty("katalystVersion") as String?)?.takeIf { it.isNotBlank() } ?: "1.0.0-beta03" + (findProperty("katalystVersion") as String?)?.takeIf { it.isNotBlank() } ?: "1.0.0-beta04" // Emits BuildInfo.KATALYST_VERSION into commonMain so StarterTemplate reads the injected value. val generateInitializrBuildInfo by tasks.registering {