fix(jdbc): unique HikariCP pool name per SlickDatabase provider (#13)#14
Merged
Conversation
Every SlickDatabase provider builds its own non-shared HikariCP pool, and
akka-persistence-jdbc names them all `slick.db` (Database.forConfig("slick.db",
config); Slick defaults poolName to the config path). In a single JVM this
produces multiple pools sharing one name, colliding on JMX MBean registration
once `registerMbeans=true` ("JMX name (slick.db) is already registered") and
breaking HikariCP's Prometheus tracker (keyed by pool name).
Inject a unique `slick.db.poolName` (`slick.db-<providerClass>-<counter>`) per
provider before akka builds the pool, only when a `slick.db` block is present
and no poolName was set explicitly. Names are sanitized to be JMX/Prometheus
safe and `getClass.getSimpleName` is guarded against the JDK 8 InternalError.
Adds SlickDatabasePoolNameSpec (H2): distinct names per provider, explicit
poolName respected, and distinct JMX MBeans under registerMbeans=true.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #14 +/- ##
==========================================
+ Coverage 61.05% 61.34% +0.29%
==========================================
Files 95 95
Lines 1854 1868 +14
==========================================
+ Hits 1132 1146 +14
Misses 722 722
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Fixes the HikariCP pool-name collision described in #13.
Every
SlickDatabaseprovider (JdbcSchema,JdbcStateProvider,ColumnMappedJdbcStateProvider,JdbcOffsetProvider, …) builds its ownnon-shared HikariCP pool. akka-persistence-jdbc 5.0.4 builds each via
Database.forConfig("slick.db", config), and Slick'sHikariCPJdbcDataSourcedefaults
poolNameto the config path → every pool is namedslick.db.In a single JVM this yields multiple distinct pools sharing one name. As soon as
a consumer sets
slick.db.registerMbeans = true, only the first pool registerscom.zaxxer.hikari:type=Pool (slick.db); the rest fail withJMX name (slick.db) is already registered. The same name clash breaksHikariCP's native Prometheus tracker (collectors are keyed by pool name).
Approach
Approach #1 (unique pool names) from the issue — lowest blast radius, no
lifecycle change.
In
SlickDatabase, inject a uniqueslick.db.poolNameinto the config beforehanding it to
SlickExtension(system).database(config):slick.db-<providerClass>-<counter>(JVMAtomicLongcounterguarantees uniqueness even for multiple instances of the same class).
slick.dbblock is present and nopoolNamewas setexplicitly (an explicit
slick.db.poolNameis respected; configs without aslick.dbblock pass through unchanged).[A-Za-z0-9._-]so they are valid as a JMXObjectNamevalue and as a Prometheus label.getClass.getSimpleNameis guarded withTry(avoids the JDK 8InternalError: Malformed class nameon synthetic/anonymous classes).The shared journal/snapshot/read-journal pool (
use-shared-db) is built by akkaitself and keeps its own default name — out of scope, and it does not collide
with the new
slick.db-…names.Tests
New
SlickDatabasePoolNameSpec(H2, no Docker):slick.db.poolNameis left untouched;registerMbeans = true, two pools register distinct JMX MBeans.These assertions fail without the fix (both pools would be named
slick.db).Verification
jdbc/scalafmtCheck✅+ jdbc/compile(Scala 2.12.20 + 2.13.16) ✅Acceptance (issue #13)
registerMbeans=true, noalready registeredERRORs; one MBean perlive pool with distinct names.
Addresses #13. (Left open intentionally — not auto-closing via keyword.)
🤖 Generated with Claude Code