Releases: bluetape4k/bluetape4k-leader
Release list
0.4.0
Highlights
bluetape4k-leader 0.4.0 improves the leader-election adoption story for the bluetape4k-dependencies 1.3.x train. It adds runnable backend examples, documents backend promotion gates and benchmark evidence, fixes Kubernetes/Fabric8 runtime compatibility, and rebuilds diagrams so lock-state and scheduling flows are understandable from the README.
Related: #487 #488 #483 #484 #485 #498
Backend examples and scheduling flows
- Added DynamoDB scheduled export and ZooKeeper scheduler examples.
- Made the existing Ktor, Spring AOP, batch scheduler, cache warmer, migration gate, and leader-trigger examples easier to navigate with scenario-level diagrams.
- Clarified lock-state routes and semantic colors so readers can distinguish active leadership, standby state, ownership transfer, and backend-specific lock behavior.
Related: #487 #488 #492 #493 #496 #505 #506
Backend evidence and promotion rules
- Documented preview backend promotion gates so users can tell which backends are stable, preview, or benchmark-backed.
- Captured MongoDB suspend benchmark evidence and auto-extend backend benchmark guidance.
- Restored
leader-spring-bootcoverage above the release threshold.
Related: #483 #484 #485 #500
Runtime and compatibility fixes
- Restored Kubernetes example runtime compatibility and isolated the Fabric8 Vert.x 4 runtime needed by K3s tests.
- Replaced deprecated leader APIs and kept compile-test warnings clean.
- Warmed snapshot test dependencies and hardened Central snapshot metadata retries in scheduled workflows.
Related: #498 #481 #527 #528 #469 #471 #473 #475 #477 #479
Release-train alignment
- Aligned the release line with
bluetape4k-bom 1.11.0, refreshed common/OpenTelemetry catalog aliases, and prepared the repo for the coordinated dependencies train. - Kept published dependency coordinates current in README material.
Related: #501 #503 #510 #525
Documentation and diagrams
- Rebuilt source-backed diagrams for core, Lettuce, Redisson, Exposed JDBC/R2DBC, Hazelcast, MongoDB, ZooKeeper, etcd, Kubernetes Lease, Consul, Ktor scheduling, Spring Boot, Micrometer, batch scheduler, cache warmer, and Prometheus dashboard flows.
- Added reader-first module architecture and scenario diagrams instead of leaving users to infer behavior from implementation links.
Related: #493 #495 #496 #505 #506 #507 #543
Contributors
Thanks to everyone who contributed to this release.
- Sunghyouk Bae sunghyouk.bae@gmail.com
- debop sunghyouk.bae@gmail.com
- dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Full Changelog: 0.3.1...0.4.0
0.3.1
Changed
- Updated the
bluetape4k-exposedtest helper line to1.10.0and imported
thebluetape4k-exposed-bomas an implementation-scoped platform in the
publishable Exposed leader modules. - Updated the default bluetape4k dependencies catalog ref to
catalog/2026-06-01-00for release workflow alignment.
Contributors
- debop sunghyouk.bae@gmail.com
Full Changelog: 0.3.0...0.3.1
0.3.0
Added
- Added Kubernetes Lease per-slot group election support with Nightly-backed
coverage for the safe slot contract. - Added framework-neutral leader event callback handles for callers that need
lifecycle events without binding to Spring or Ktor. - Added runnable adoption examples for etcd reconcilers, Consul maintenance
windows, strategic election, virtual-thread leader jobs, and Redisson-backed
long-running leader jobs. - Added a runnable virtual-thread leader runner example for high-concurrency
leader-only maintenance work. (#426) - Added a runnable Redisson watchdog example for long-running leader-only jobs
protected by bluetape4k lease auto-extension. (#425)
Changed
- Opened the
0.3.0development line after publishing0.2.2. - Updated public README dependency snippets to the
0.3.0release coordinate. - Refreshed README architecture, benchmark, and example workflow diagrams with
reproducible rendering evidence. - Aligned the Ktor example and Ktor-facing consumer guidance with shared
bluetape4k Ktor health modules. - Made preview backend release gate evidence explicit in the Nightly summary
documentation and workflow surface. (#417) - Updated the
bluetape4k-exposedtest helper reference from1.9.2-SNAPSHOT
to the published1.9.2release. - Aligned the AWS SDK BOM with the central
bluetape4k-dependenciescatalog. - Consumed the
bluetape4k-projects1.10.0BOM line.
Fixed
- Applied central catalog-managed Netty 4.1, Protobuf, Fabric8, and Vert.x 4
dependency overrides for Dependabot security alerts. (#389) - Forced Gradle plugin classpath MySQL and Protobuf dependencies onto the
central catalog lines to clear plugin-classpath Dependabot alerts. (#389) - Removed the unused root
apply falseExposed plugin declaration so GitHub
dependency submission no longer reports its stale plugin POM transitives. (#389) - Removed the unused Exposed migration plugin from
examples/migration-gate;
the example uses runtime Exposed APIs directly and does not need plugin tasks. (#389) - Kept Spring group stream support explicitly rejected until per-slot group lease
extension semantics are defined.
Performance
- Added Redis lease-extension benchmark evidence for Lettuce and Redisson.
- Added SQL backend and preview backend benchmark evidence to make release
recommendations measurement-backed.
Contributors
- Sunghyouk Bae sunghyouk.bae@gmail.com
- debop sunghyouk.bae@gmail.com
Full Changelog: 0.2.2...0.3.0
0.2.2
Added
- Expanded DynamoDB leader election edge-case coverage. (#366, PR #368)
- Added preview backend state snapshot contract coverage for Consul, DynamoDB, and etcd. (#374, PR #381)
- Added KDoc for DynamoDB leader factory classes and extension functions. (#365, PR #369)
Changed
- Updated public README dependency snippets to the
0.2.2release coordinate. (#375) - Made the preview backend release gate explicit for Consul, DynamoDB Local, etcd, and Kubernetes Lease; K3s runtime coverage remains in Nightly full. (#376, PR #382)
- Shared the DynamoDB Local test launcher through
bluetape4k-testcontainersto remove duplicated container wiring. (#367, PR #370)
Fixed
- Bound Consul blocking wait and acquire cleanup paths to the configured request timeout budget. (#372, PR #379)
- Bound etcd cleanup waits to configured timeout budgets. (#373, PR #380)
Contributors
- debop sunghyouk.bae@gmail.com
Full Changelog: 0.2.1...0.2.2
0.2.1
Release 0.2.1
See CHANGELOG.md for details.
Contributors
- debop sunghyouk.bae@gmail.com
Full Changelog: 0.2.0...0.2.1
0.2.0
Added
leader-k8sKubernetes Lease backend with K3s integration coverage. (#335)leader-etcdetcd v3 backend with blocking, async, and suspend election paths. (#227)leader-consulConsul KV/session backend with blocking and suspend leader election. (#345)leader-dynamodbAWS DynamoDB backend for conditional-write based leader election. (#228)- Per-lock
StateFlow<LeaderState>support for coroutine-native state observation. (#222) - DB server-time based lock acquisition support for Exposed JDBC/R2DBC backends. (#39)
- Runnable adoption examples for Kubernetes operator leadership and leader-coordinated rate limiting. (#231, #229)
- K3s Lease integration example coverage. (#248)
Changed
- Replaced internal
runBlockingbridge delegates with a pure-suspendExtendDelegatecontract. (#271) - Updated
bluetape4k-exposedtest helper references to1.9.0. - Updated public README dependency snippets to the
0.2.0release coordinate.
Fixed
- Reworked Exposed JDBC cancellation handling to rethrow
CancellationExceptioninstead of swallowing it throughrunCatching. (#304) - Replaced wall-clock wait deadlines with monotonic timeout budgets in Exposed JDBC, MongoDB, and Lettuce acquisition loops. (#305, #306, #308, #309)
- Fixed Kubernetes Lease annotation conversion to avoid mutating the original Lease instance in-place. (#347)
- Added missing Kubernetes Lease suspend elector K3s scenarios. (#349)
- Synchronized Korean README content with observability and Ktor management route documentation. (#287)
- Expanded Ktor management registry KDoc and translated WebhookPoller public documentation/comments to English. (#288, #348)
Removed
- Removed all APIs deprecated before the 0.1.0 GA line. (#269)
Contributors
- Sunghyouk Bae sunghyouk.bae@gmail.com
- debop sunghyouk.bae@gmail.com
- dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Full Changelog: 0.1.0...0.2.0
0.1.0
First public release of bluetape4k-leader. All APIs are stable unless noted as experimental.
Breaking Changes
-
runIfLeader()never throws on lock contention: returnsnullinstead of propagating
backend exceptions when the lock is not acquired — aligns with ShedLock skip-on-contention
semantics.CancellationExceptionandInterruptedExceptionare still rethrown. (PR #15)// Null means "not elected" or "action threw" — check logs val result = leaderElector.runIfLeader("job") { riskyWork() } // To preserve exception propagation, wrap in the action: leaderElector.runIfLeader("job") { try { riskyWork() } catch (e: MyException) { handleError(e); throw e } }
-
leader-exposed-jdbc:ExposedJdbcLeaderElector.runIfLeader()now returnsnullinstead
of rethrowing action exceptions.CancellationExceptionandInterruptedExceptionare still
rethrown. (issue #50) -
leader-exposed-r2dbc: Same change forExposedR2DbcSuspendLeaderElector.runIfLeader().
CancellationExceptionis still rethrown. -
leader-exposed-jdbc/leader-exposed-r2dbc: Elector factories now accept an optional
historyRecorderparameter (SafeLeaderHistoryRecorder?/SuspendSafeLeaderHistoryRecorder?).
The previousrecordHistoryoption in election options is superseded. -
LeaderElection/LeaderGroupElectionrenamed toLeaderElector/LeaderGroupElector
for consistency across all interfaces. (PR #106, #123, #125) -
Duration APIs: migrated from
java.time.Durationtokotlin.time.Duration. (PR #126) -
LeaderElectionEvent.Electednow carries optionalleaderId: String?and
leaseExpiry: Instant?fields (both default tonull). Compiled callers that construct
Elected(lockName)positionally will fail to link against new bytecode; recompilation is
required (source-compatible). -
Spring Boot 3/4 split consolidated:
leader-spring-boot-common,leader-spring-boot3, and
leader-spring-boot4merged into a singleleader-spring-bootmodule. (PR #105)
Added
leader-core — Core interfaces and local in-process implementations:
LeaderElector— blocking single-leader interfaceAsyncLeaderElector—CompletableFuture-based async interfaceVirtualThreadLeaderElector— virtual-thread-per-election interfaceSuspendLeaderElector— Kotlin coroutine suspend interfaceLeaderGroupElector— blocking multi-leader (semaphore) interfaceSuspendLeaderGroupElector— coroutine multi-leader interfaceLeaderElectionOptions(waitTime, leaseTime)— shared option data classLeaderGroupElectionOptions(maxLeaders, waitTime, leaseTime)— group option data class- Local implementations:
LocalLeaderElector,LocalLeaderGroupElector,
LocalSuspendLeaderElector,LocalSuspendLeaderGroupElector,LocalAsyncLeaderElector,
LocalVirtualThreadLeaderElector LockAssert—assertLocked()/assertLocked(lockName)/isLocked()and suspend variantsLockExtender—extendActiveLock(Duration): Boolean+ detailed sealedExtendOutcomeresult- suspend variants
LeaderLockHandlesealed class (Real/FailOpen) — explicit lease handleLeaderLeaseAutoExtender— periodic background lease renewal withshutdown()/restart()ListeningLeaderElector/ListeningLeaderGroupElector— listener-aware decorators with a hot
events: Flow<LeaderElectionEvent>stream (issue #40, PR #146)TenantScopedLeaderElectors—forTenant(tenantId)extension functions for multi-tenant
lock-name scoping (issue #42)- Strategic election API (issue #29, #31, #32):
CandidateInfo,ElectionStrategy,CandidateScorerinterfaces- Built-in strategies:
FifoElectionStrategy,RandomElectionStrategy,ScoredElectionStrategy - Built-in scorers:
IdleTimeScorer,SuccessRateScorer,RecentSuccessScorer,WeightedScorer - Redis
CandidateRegistry(Redisson sorted-set/hash + TTL; Lettuce variant included)
LeaderSlotaudit identity propagation:LeaderSlot(lockName, leaderId)propagates to
LeaderRunResult.Elected.leaderId(issue #72)
leader-redis-lettuce — Lettuce Redis backend:
LettuceLeaderElector— blocking, usesSET NX PXviaLettuceLockLettuceLeaderGroupElector— blocking multi-leader viaLettuceSlotTokenGroup(ZSET + Lua TTL)LettuceSuspendLeaderElector— coroutine single-leaderLettuceSuspendLeaderGroupElector— coroutine multi-leaderLettuceLock,LettuceSuspendLock— Redis distributed lock primitives (self-contained, nobluetape4k-lettucedependency)
leader-redis-redisson — Redisson Redis backend:
RedissonLeaderElector— blocking viaRLock.tryLock()RedissonLeaderGroupElector— blocking multi-leader viaRPermitExpirableSemaphoreRedissonSuspendLeaderElector— coroutine single-leader with PID-seeded Snowflake lock IDRedissonSuspendLeaderGroupElector— coroutine multi-leader
leader-exposed-core: Shared Exposed table DDL (LeaderLockTable, LeaderGroupLockTable) for
JDBC and R2DBC backends. (issue #23)
leader-exposed-jdbc — Exposed JDBC blocking backend (issue #21, PR #52):
ExposedJdbcLeaderElector— blocking single-leader (sync +CompletableFutureasync)ExposedJdbcLeaderGroupElector— blocking multi-leader- H2/PostgreSQL/MySQL Testcontainers integration tests
leader-exposed-r2dbc — Exposed R2DBC coroutine backend (issue #22, PR #62):
ExposedR2DbcSuspendLeaderElector— coroutine single-leaderExposedR2DbcSuspendLeaderGroupElector— coroutine multi-leader- R2DBC PostgreSQL Testcontainers integration tests
leader-mongodb — MongoDB backend (issue #8, PR #46):
MongoLeaderElector— blocking,findOneAndUpdateupsert +deleteOne(token)owner-only releaseMongoSuspendLeaderElector— coroutine, Kotlin coroutine driverMongoLeaderGroupElector— blocking multi-leader (lockName:slot:Nslot model)MongoSuspendLeaderGroupElector— coroutine multi-leader (dual-collection design)- TTL index auto-creation at startup
- 82.4% line coverage (42 tests, Testcontainers MongoDB)
leader-hazelcast — Hazelcast IMap token-lock backend (issue #9):
HazelcastLeaderElector,HazelcastLeaderGroupElector— blocking single/multi-leaderHazelcastSuspendLeaderElector,HazelcastSuspendLeaderGroupElector— coroutine variants
leader-zookeeper — ZooKeeper/Curator backend. (PR #138)
leader-micrometer — Micrometer metrics integration:
MicrometerLeaderElectionListenerrecordsleader.election.eventswithlock.nameandeventtags (issue #40, PR #146)
leader-spring-boot — Spring Boot 4 auto-configuration + AOP:
@LeaderElection/@LeaderGroupElectionannotations with AspectJ compile-time weaving (CTW)- Supports
suspend,Mono,Flux, and KotlinFlowreturn types (#74, #90, #91)@LeaderElection(streamBounded = true)explicit opt-in for bounded streams
LeaderAnnotationValidatorBeanPostProcessor— startup validation; blocks unsafe return types
(CompletableFuture,Deferred, etc.) (PR #79)LockAssert/LockExtenderintegration in AOP aspect (issue #79)LeaderMetricsHealthIndicator— Spring Boot Actuator health indicator (registered asleaderMetricsHealthIndicator)LeaderLeaseAutoExtenderLifecycle— context-lifecycle-aware auto-extender integration- Backend auto-configurations: Lettuce, Redisson, Exposed JDBC, Exposed R2DBC, MongoDB, Hazelcast
LeaderProperties—bluetape4k.leader.*configuration properties
leader-ktor — Ktor 3.x integration (issue #37, PR #164):
LeaderElectionPlugin—createApplicationPluginDSL,SuspendLeaderElector-basedApplication.leaderScheduled(lockName, period) { }— Spring@Scheduled-style leader-only
periodic task helper; auto-cancelled onApplicationStopped
leader-bom — Bill of Materials for consumers. All leader-* modules included; BOM users
do not need to specify individual versions.
examples/ — Runnable example applications (issue #36):
batch-scheduler— Lettuce Redis periodic batch single-execution (PR #159)migration-gate— Exposed JDBC boot-time schema migration gate (PR #160)webhook-poller— MongoDB single-instance webhook polling (PR #161)cache-warmer— Hazelcast per-partition leader cache warming (PR #162)tenant-aggregator— Exposed R2DBC coroutine multi-tenant aggregation (PR #163)ktor-app— Ktor 3.x + Lettuce RedisleaderScheduled()demo (PR #166)prometheus-dashboard— Spring Boot + Prometheus/Grafana leader metrics dashboard
CI/CD (issue #13, #35, PR #19, #20, #44, #135):
- GitHub Actions build, test, secret-scan, Gradle wrapper validation
- Nightly SNAPSHOT auto-publish (on test success only)
- Parallel test jobs for Lettuce and Redisson backends
Changed
LeaderElectionAspect/LeaderGroupElectionAspectouter catch narrowed toException(not
Throwable) to letOutOfMemoryError/StackOverflowErrorpropagate.LeaderElectionOptions,LeaderGroupElectionOptions,LeaderGroupStatevalidate eagerly in
init {}(waitTime ≥ 0,leaseTime > 0,maxLeaders ≥ 1). (PR #25)ExposedJdbcGroupLock.tryLock()return type changed toBoolean?:null= DB error,
false= slot contention,true= acquired. (issue #60, PR #63)- Suspend tests use
runBlocking(Dispatchers.IO)instead ofrunTestfor real-IO
(MongoDB / Testcontainers) tests. - CI uses paths-filter and retry configuration to reduce unnecessary work and transient failures.
(PR #135) - Prometheus export coverage verified through
PrometheusServerscrape tests. (PR #144) leader-bomNMCP aggregation and Central Snapshots publishing fixed. (PR #140)- factory
create()I/O failures now respect the configured failure mode. (PR #107) @ConfigurationPropertiesadded to AOP properties binding where missing. (PR #93)
Fixed
- **Coroutine cancellation...