Skip to content

domgew/kedis

Repository files navigation

Kedis

Maven Central Latest Tag Publish Test Kotlin Licence: MIT

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.

Installation

dependencies {
    // ...

    implementation("io.github.domgew:kedis:<current_version>")

    // OR just for JVM:
    implementation("io.github.domgew:kedis-jvm:<current_version>")

    // ...
}
repositories {
    mavenCentral()

    // ...
}

Documentation

See Dokka-generated docs. For available commands see the documentation of the commands package and the KedisConfiguration for the available configuration options.

Quick Start

With Sealed Polymorphism

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")
    }

With DSL-Style Builder

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")
    }

With Connection Pool

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")
    }

Targets

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

Library Comparison

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)

Examples

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
Loading

Contributors 2

  •  
  •  

Languages