Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,70 @@ A lib that regulates the cache-based requests an application receives in terms o
- (If link this lib with Spring) Spring Boot 2.7 (Spring Framework 5.3) or later if you are a user.

## Usage
- Choose from the following based on your platform (There is a detailed explanation in the wiki.)

Choose a module based on your platform (there is a detailed explanation in the wiki):

`implementation("com.linecorp.cse.reqshield:core:{version}")`<br>
`implementation("com.linecorp.cse.reqshield:core-reactor:{version}")`<br>
`implementation("com.linecorp.cse.reqshield:core-kotlin-coroutine:{version}")`<br>
`implementation("com.linecorp.cse.reqshield:core-spring:{version}")`<br>
`implementation("com.linecorp.cse.reqshield:core-spring-webflux:{version}")`<br>
`implementation("com.linecorp.cse.reqshield:core-spring-webflux-kotlin-coroutine:{version}")`<br>

### Release versions

Release versions are available from Maven Central. Add Maven Central and use a release version such as `1.0.0`:

```kotlin
repositories {
mavenCentral()
}

dependencies {
implementation("com.linecorp.cse.reqshield:core:1.0.0")
}
```

### Dev snapshot versions

Dev versions are published as Maven snapshots and require the Maven Central Snapshot repository. Use a snapshot version
such as `1.0.0-SNAPSHOT`:

```kotlin
repositories {
mavenCentral()
maven {
name = "MavenCentralSnapshots"
url = uri("https://central.sonatype.com/repository/maven-snapshots/")
mavenContent {
snapshotsOnly()
}
}
}

dependencies {
implementation("com.linecorp.cse.reqshield:core:1.0.0-SNAPSHOT")
}
```

Snapshot versions can be updated without changing the version string. If Gradle continues to use a cached snapshot,
refresh dependencies with `./gradlew build --refresh-dependencies`.

## Testing & Integration Tips

### Integration tests with Redis (Testcontainers)

- Redis-backed integration tests using Testcontainers always run as part of module test tasks.
- Requirements:
- A working local Docker daemon with network access to pull `redis:6.2.7-alpine` on first run.
- Sufficient permissions to start containers from tests.
- A working local Docker daemon with network access to pull `redis:6.2.7-alpine` on first run.
- Sufficient permissions to start containers from tests.
- If you need to temporarily bypass Redis ITs locally (e.g., no Docker), run specific unit-test-only tasks or exclude the example modules when invoking Gradle.

### WebFlux null handling

- `@ReqShieldCacheable(nullHandling = ...)` controls how `null` values are emitted in WebFlux:
- `EMIT_EMPTY` (default): map `null` to `Mono.empty()`.
- `ERROR`: throw an `IllegalStateException` if a `null` value is produced.
- `EMIT_EMPTY` (default): map `null` to `Mono.empty()`.
- `ERROR`: throw an `IllegalStateException` if a `null` value is produced.

### Cache key layout

Expand All @@ -53,9 +94,9 @@ A lib that regulates the cache-based requests an application receives in terms o
- Every lock acquisition carries an ownership token. Only the holder that acquired the lock can release it, so a slow
holder whose lock already expired can no longer release the lock of the next holder.
- Recommended Redis implementation:
- Lock: `SET {lockKey} {token} NX PX {ttlMillis}` (atomic; never `SETNX` followed by a separate `PEXPIRE`)
- Unlock: compare-and-delete in a Lua script, e.g.
`if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end`
- Lock: `SET {lockKey} {token} NX PX {ttlMillis}` (atomic; never `SETNX` followed by a separate `PEXPIRE`)
- Unlock: compare-and-delete in a Lua script, e.g.
`if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end`
- The example modules contain working implementations for `RedisTemplate`, `ReactiveRedisTemplate` and the coroutine
extensions.

Expand Down
Loading