Skip to content

Commit

Permalink
document the write-behind-rxjava example
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-manes committed Aug 6, 2023
1 parent 2c7b878 commit f3a9345
Show file tree
Hide file tree
Showing 23 changed files with 534 additions and 708 deletions.
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ updates:
directory: examples/coalescing-bulkloader
schedule:
interval: daily
- package-ecosystem: maven
- package-ecosystem: gradle
directory: examples/write-behind-rxjava
schedule:
interval: daily
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
|| ([[ $? -eq 124 ]] && echo "Timeout reached, but that's OK")
- name: Write-behind (rxjava)
working-directory: examples/write-behind-rxjava
run: ./mvnw test
run: ./gradlew build
- name: Coalescing Bulkloader
working-directory: examples/coalescing-bulkloader
run: ./mvnw test
Expand Down
4 changes: 3 additions & 1 deletion examples/graal-native/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Graal native image uses ahead-of-time compilation to build an optimized executable.
[Graal native image][] uses ahead-of-time compilation to build an optimized executable.

### Install GraalVM using sdkman.io

Expand Down Expand Up @@ -43,3 +43,5 @@ gradle run -Pagent
```console
./gradlew nativeTest
```

[Graal native image]: https://www.graalvm.org/22.0/reference-manual/native-image
2 changes: 1 addition & 1 deletion examples/hibernate/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Hibernate] can be configured to use a [second-level cache] to reduce the number of accesses
[Hibernate][] can be configured to use a [second-level cache] to reduce the number of accesses
to the database by caching data in memory to be shared between sessions.

In [hibernate.conf](src/main/resources/hibernate.properties) specify the JCache provider and enable
Expand Down
14 changes: 3 additions & 11 deletions examples/resilience-failsafe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,14 @@ failsafe.get(() -> cache.get(key, key -> /* intermittent failures */ ));

// Optionally, retry inside the cache load for asynchronous calls
AsyncCache<K, V> asyncCache = Caffeine.newBuilder().buildAsync();
asyncCache.get(key, (key, executor) -> failsafe.getAsync(() -> /* intermittent failure */));
asyncCache.get(key, (key, executor) -> failsafe.getAsync(() -> /* intermittent failure */ ));
```

### Timeout
A [timeout policy][timeout] will cancel the execution if it takes too long to complete.

```java
var retryPolicy = RetryPolicy.builder()
.withDelay(Duration.ofSeconds(1))
.withMaxAttempts(3)
.build();
var timeout = Timeout.builder(Duration.ofSeconds(1)).withInterrupt().build();
var timeout = Timeout.builder(Duration.ofSeconds(10)).withInterrupt().build();
var failsafe = Failsafe.with(timeout, retryPolicy);

Cache<K, V> cache = Caffeine.newBuilder().build();
Expand All @@ -40,12 +36,8 @@ failsafe.get(() -> cache.get(key, key -> /* timeout */ ));
A [fallback policy][fallback] will provide an alternative result for a failed execution.

```java
var retryPolicy = RetryPolicy.builder()
.withDelay(Duration.ofSeconds(1))
.withMaxAttempts(3)
.build();
var fallback = Fallback.of(/* fallback */);
var failsafe = Failsafe.with(fallback, retryPolicy);
var failsafe = Failsafe.with(fallback, timeout, retryPolicy);

Cache<K, V> cache = Caffeine.newBuilder().build();
failsafe.get(() -> cache.get(key, key -> /* failure */ ));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@CheckReturnValue
package com.github.benmanes.caffeine.examples.resilience;

import com.google.errorprone.annotations.CheckReturnValue;
Binary file not shown.
18 changes: 0 additions & 18 deletions examples/write-behind-rxjava/.mvn/wrapper/maven-wrapper.properties

This file was deleted.

27 changes: 27 additions & 0 deletions examples/write-behind-rxjava/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Using [RxJava][rxjava] observable sequences, you can asynchronously write to an external resource
after updating the cache. This approach offers a potential performance boost by batching write
operations, albeit with a trade-off of potential data inconsistency.

A [buffer][] operator gathers changes within a specified time window. This window may encompass
multiple updates to the same key so when merging these changes into a single write any outdated
modifications can be discarded. Subsequently, the subscriber is notified to execute the batch
operation.

```java
var subject = PublishSubject.<Entry<K, V>>create().toSerialized();
subject.buffer(10, TimeUnit.SECONDS)
.map(entries -> entries.stream().collect(
toMap(Entry::getKey, Entry::getValue, (v1, v2) -> /* latest */ v2)))
.subscribeOn(Schedulers.io())
.subscribe(entries -> System.out.println(entries));

Cache<K, V> cache = Caffeine.newBuilder().build();
cache.asMap().compute(key, (k, v) -> {
var value = /* mutations */
subject.onNext(Map.entry(key, value));
return value;
});
```

[rxjava]: https://github.com/ReactiveX/RxJava
[buffer]: http://reactivex.io/RxJava/3.x/javadoc/io/reactivex/rxjava3/core/Observable.html#buffer-long-java.util.concurrent.TimeUnit-
27 changes: 27 additions & 0 deletions examples/write-behind-rxjava/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
plugins {
`java-library`
alias(libs.plugins.versions)
}

dependencies {
implementation(libs.caffeine)
implementation(libs.rxjava)

testImplementation(libs.awaitility)
testImplementation(libs.junit)
}

testing.suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
}
}

java.toolchain.languageVersion = JavaLanguageVersion.of(
System.getenv("JAVA_VERSION")?.toIntOrNull() ?: 11)

tasks.withType<JavaCompile>().configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = java.toolchain.languageVersion
}
}
15 changes: 15 additions & 0 deletions examples/write-behind-rxjava/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[versions]
awaitility = "4.2.0"
caffeine = "3.1.7"
junit = "5.10.0"
rxjava = "3.1.6"
versions = "0.47.0"

[libraries]
awaitility = { module = "org.awaitility:awaitility", version.ref = "awaitility" }
caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }

[plugins]
versions = { id = "com.github.ben-manes.versions", version.ref = "versions" }
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-rc-3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit f3a9345

Please sign in to comment.