Kedis is a Redis client library for Kotlin Multiplatform (JVM + Native). This is possible via Ktor Network sockets, which provides native and JVM sockets with a unified interface.
dependencies {
// ...
implementation("io.github.domgew:kedis:<current_version>")
// OR just for JVM:
implementation("io.github.domgew:kedis-jvm:<current_version>")
// ...
}
repositories {
mavenCentral()
// ...
}
See Dokka-generated docs.
For available commands see the documentation of the commands
package and the KedisConfiguration for the available configuration options.
KedisClient(
configuration = KedisConfiguration(
// OR: KedisConfiguration.Endpoint.UnixSocket(path)
endpoint = KedisConfiguration.Endpoint.HostPort(
host = "127.0.0.1",
port = 6379, // optional, 6379 is the default
),
// OR: KedisConfiguration.Authentication.NoAutoAuth
authication = KedisConfiguration.Authentication.AutoAuth(
password = "secret",
username = "admin", // optional
),
connectionTimeout = 250.milliseconds,
keepAlive = true, // optional, true is the default
databaseIndex = 1, // optional, 0 is the default
),
)
.use { client ->
val testValue = client.execute(
KedisValueCommands.get(
key = "test",
),
)
?.let {
"'$it'"
}
?: "NULL"
println("Test value: $testValue")
}
KedisClient.builder {
// OR: unixSocket
hostAndPort(
host = "127.0.0.1",
port = 6379, // optional, 6379 is the default
)
// OR: noAutoAuth (optional)
autoAuth(
password = "secret",
username = "admin", // optional
)
connectTimeout = 250.milliseconds
keepAlive = true // optional, true is the default
databaseIndex = 1 // optional, 0 is the default
}
.use { client ->
val testValue = client.execute(
KedisValueCommands.get(
key = "test",
),
)
?.let {
"'$it'"
}
?: "NULL"
println("Test value: $testValue")
}
Additional library (io.github.domgew:kop) needed.
KotlinObjectPool(
KotlinObjectPoolConfig(
maxSize = 3,
keepAliveFor = 2.minutes,
strategy = KotlinObjectPoolStrategy.LIFO, // OR: FIFO
),
) {
// OR: KedisClient(configuration)
KedisClient.builder {
hostAndPort("127.0.0.1", 6379)
noAutoAuth()
connectTimeout = 250.milliseconds
keepAlive = true
}
}
.use { pool ->
val testValue = pool.withObject { client ->
client.execute(
KedisValueCommands.get(
key = "test",
),
)
}
?.let {
"'$it'"
}
?: "NULL"
println("Test value: $testValue")
}
Supported Targets:
- JVM
- Native: Linux X64
- Native: Linux ARM64
- Native: macOS X64
- Native: macOS ARM64
- Native: mingw X64
Potential Future Targets (mostly currently no Ktor Network support):
- JS: NodeJS
- JVM: GraalVM Native
Non-Targets - Never Coming:
- Native 32 bit targets
- Native consumer targets (android, iOS, tvOS, watchOS, ...)
- JS: Browser
Kedis | Kreds | |
---|---|---|
Automated Integration Tests | ✓ | ✓ |
JVM Support | ✓ | ✓ |
Native Linux X64 Support | ✓ | ✗ |
Native Linux ARM64 Support | ✓ | ✗ |
Native macOS X64 Support | ✓ | ✗ |
Native macOS ARM64 Support | ✓ | ✗ |
Host + Port Support | ✓ | ✓ |
UNIX Socket Support | ✓ | ✗ |
Binary Data Support | ✓ | ✗ |
Stable Authentication | ✓ (with AutoAuth) | ✗ (errors when reconnecting) |
Mature | ✗ | ✓ |
Full-Featured | ✗ | ✓ |
Pub-Sub Support | ✗ | ✓ |
Pipelining Support | ✓ | ✓ |
GraalVM Native Support | ✗ | ✗ |
Exclusive Configuration | Compile Time / Sealed Polymorthism | Run Time / Builder Exception |
Responses | Strictly Typed | Semi-Raw |
Networking | Ktor Network (Kotlin) | Netty (Java) |
Redis Protocol (En-/Decoding) | Custom (Kotlin) | Netty (Java) |
Redis Protocol (Interfacing) | Custom (Kotlin) | Custom (Kotlin) |
See example project.
Caching concept ("get or generate") with gradual service degradation:
- Try to connect to the Redis server (KedisClient.connect) - here you would already see, whether the server is reachable, if not, fall back to generation -> EXIT with generation
- Try to get the value for the key (KedisClient.get/getBinary) - if it is
null
, it does not exist - it could however fail under some circumstances, so use a try-catch block -> EXIT with generation - When a non-null value was retrieved, you can return it (maybe close the connection/client (KedisClient.close) - with dependency injection request scopes, this might however not be desired) -> EXIT
- Otherwise, use a callback to generate the value (e.g. call an external API)
- Try to set the value for the key (KedisClient.set/setBinary) with the desired options (e.g. time-to-live, value replacement, ...) - this might however fail under some circumstances
- Return the generated value (maybe close the connection)
---
title: Get or Generate
---
flowchart
start([Value requested])
isAvailable{Is Redis available?}
getFromCache[Get from cache]
generateBeforeExit[Generate]
generateBeforeWrite[Generate]
writeToCache[Write to cache]
hasCachedValue{Has cached value?}
returnValue([Return value])
exitWithError([Exit with error])
start --> isAvailable
isAvailable -- no --> generateBeforeExit
isAvailable -- yes --> getFromCache
generateBeforeExit -- success --> returnValue
generateBeforeExit -- error --> exitWithError
getFromCache -- error --> generateBeforeExit
getFromCache -- success --> hasCachedValue
hasCachedValue -- no --> generateBeforeWrite
hasCachedValue -- yes --> returnValue
generateBeforeWrite -- success --> writeToCache
generateBeforeWrite -- error --> exitWithError
writeToCache -- error --> returnValue
writeToCache -- success --> returnValue