Skip to content
Merged
Show file tree
Hide file tree
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
101 changes: 4 additions & 97 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,74 +45,20 @@ jobs:
restore-keys: ${{ runner.os }}-m2

- name: Compile project
run: mvn clean compile test-compile
run: mvn formatter:format

- name: Run unit tests
run: mvn test -Dtest=RedlockConfigurationTest

- name: Run integration tests with Testcontainers
run: mvn test -Dtest=RedlockIntegrationTest
- name: Run unit and integration tests (requires Testcontainers)
run: mvn verify jacoco:report
env:
TESTCONTAINERS_RYUK_DISABLED: false

- name: Run all tests (including performance tests on nightly)
if: github.event_name == 'schedule'
run: mvn test -Dtest=RedlockPerformanceTest
run: mvn test -Dgroups=performance
continue-on-error: true
env:
TESTCONTAINERS_RYUK_DISABLED: false

- name: Generate test report
uses: dorny/test-reporter@v1
if: (success() || failure()) && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
continue-on-error: true
with:
name: Maven Tests (ubuntu-latest, Java ${{ matrix.java }})
path: 'target/surefire-reports/*.xml'
reporter: java-junit
fail-on-error: false
fail-on-empty: false

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
continue-on-error: true
with:
name: test-results-ubuntu-latest-java${{ matrix.java }}
path: |
target/surefire-reports/
target/site/jacoco/
retention-days: 30

code-quality:
name: Code Quality Analysis
runs-on: ubuntu-latest
continue-on-error: true

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: 11
distribution: 'temurin'

- name: Cache Maven dependencies
uses: actions/cache@v4
continue-on-error: true
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2

- name: Run tests with coverage
run: mvn clean test jacoco:report
continue-on-error: true

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
continue-on-error: true
Expand All @@ -121,42 +67,3 @@ jobs:
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false

build-info:
name: Build Information
runs-on: ubuntu-latest
continue-on-error: true

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: 11
distribution: 'temurin'

- name: Display build information
continue-on-error: true
run: |
echo "## Build Information" >> $GITHUB_STEP_SUMMARY
echo "- **Repository:** ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY
echo "- **Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "- **Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Java Version:** $(java -version 2>&1 | head -n 1)" >> $GITHUB_STEP_SUMMARY
echo "- **Maven Version:** $(mvn -version | head -n 1)" >> $GITHUB_STEP_SUMMARY
echo "- **Docker Version:** $(docker --version)" >> $GITHUB_STEP_SUMMARY

- name: Validate Maven POM
run: mvn validate

- name: Check for Maven wrapper
continue-on-error: true
run: |
if [ -f "mvnw" ]; then
echo "Maven wrapper found" >> $GITHUB_STEP_SUMMARY
else
echo "Maven wrapper not found (using system Maven)" >> $GITHUB_STEP_SUMMARY
fi
3 changes: 0 additions & 3 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ jobs:
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2

- name: Run unit tests
run: mvn test

- name: Run integration tests
run: mvn verify -Dmaven.test.skip.exec=false
env:
Expand Down
105 changes: 0 additions & 105 deletions .github/workflows/pr-validation.yml

This file was deleted.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

</p>


[![CI](https://github.com/Codarama/redlock4j/actions/workflows/ci.yml/badge.svg)](https://github.com/Codarama/redlock4j/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/Codarama/redlock4j/graph/badge.svg?token=EK4LMLJ533)](https://codecov.io/gh/Codarama/redlock4j)
[![Maven Central](https://img.shields.io/maven-central/v/org.codarama/redlock4j?versionSuffix=RELEASE)](https://maven-badges.herokuapp.com/maven-central/org.codarama/redlock4j)
[![Javadocs](https://www.javadoc.io/badge/org.codarama/redlock4j.svg)](https://javadoc.io/doc/org.codarama/redlock4j)
[![Java](https://img.shields.io/badge/Java-8%2B-blue.svg)](https://openjdk.java.net/)
[![Guide](https://img.shields.io/badge/mkdocs-guide-526CFE?logo=materialformkdocs&logoColor=white)](https://codarama.github.io/redlock4j/)

> [!IMPORTANT]
> This project is a personal project and is not currently affiliated or endorsed in any way with Redis or any other company. Use the software freely and at your own risk.
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ The documentation supports:

```markdown
\`\`\`java
Lock lock = redlock.lock("resource", 10000);
Lock lock = manager.createLock("resource");
\`\`\`
```

Expand Down
53 changes: 32 additions & 21 deletions docs/api/async-reactive.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ AsyncRedlock asyncLock = manager.createAsyncLock("async-resource");

### Methods

| Method | Return Type | Description |
|--------|-------------|-------------|
| `tryLockAsync()` | `CompletionStage<Boolean>` | Tries to acquire the lock |
| `tryLockAsync(Duration)` | `CompletionStage<Boolean>` | Tries with timeout |
| `unlockAsync()` | `CompletionStage<Void>` | Releases the lock |
| `isHeldByCurrentThread()` | `boolean` | Checks if held by current thread |
| `getLockKey()` | `String` | Returns the lock key |
| Method | Return Type | Description |
|------------------------------|----------------------------|---------------------------------------------------------|
| `tryLockAsync()` | `CompletionStage<Boolean>` | Tries to acquire the lock |
| `tryLockAsync(Duration)` | `CompletionStage<Boolean>` | Tries with timeout |
| `lockAsync()` | `CompletionStage<Void>` | Acquires the lock, waiting if necessary |
| `unlockAsync()` | `CompletionStage<Void>` | Releases the lock |
| `isHeldByCurrentThread()` | `boolean` | Checks if held by current thread |
| `getRemainingValidityTime()` | `Duration` | Remaining validity time, or `Duration.ZERO` if not held |
| `getHoldCount()` | `int` | Number of times the lock has been acquired, or 0 |
| `getLockKey()` | `String` | Returns the lock key |
| `extendAsync(Duration)` | `CompletionStage<Boolean>` | Extends the lock validity time |

### Example

Expand Down Expand Up @@ -74,24 +78,31 @@ RxRedlock rxLock = manager.createRxLock("rx-resource");

### Methods

| Method | Return Type | Description |
|--------|-------------|-------------|
| `tryLockSingle()` | `Single<Boolean>` | Tries to acquire the lock |
| `tryLockSingle(Duration)` | `Single<Boolean>` | Tries with timeout |
| `unlockCompletable()` | `Completable` | Releases the lock |
| `validityObservable(Duration)` | `Observable<Long>` | Emits remaining validity time |
| `getLockKey()` | `String` | Returns the lock key |
| Method | Return Type | Description |
|-----------------------------------------------------------|-------------------------|---------------------------------------------------------------------------|
| `tryLockRx()` | `Single<Boolean>` | Tries to acquire the lock |
| `tryLockRx(Duration)` | `Single<Boolean>` | Tries with timeout |
| `lockRx()` | `Completable` | Acquires the lock, waiting if necessary |
| `unlockRx()` | `Completable` | Releases the lock |
| `tryLockWithRetryRx(int maxRetries, Duration retryDelay)` | `Single<Boolean>` | Tries to acquire with retry logic |
| `validityObservable(Duration checkInterval)` | `Observable<Duration>` | Emits remaining validity time at each check |
| `lockStateObservable()` | `Observable<LockState>` | Emits lock state changes (ACQUIRING, ACQUIRED, RELEASED, EXPIRED, FAILED) |
| `isHeldByCurrentThread()` | `boolean` | Checks if held by current thread |
| `getRemainingValidityTime()` | `Duration` | Remaining validity time, or `Duration.ZERO` if not held |
| `getHoldCount()` | `int` | Number of times the lock has been acquired, or 0 |
| `getLockKey()` | `String` | Returns the lock key |
| `extendRx(Duration)` | `Single<Boolean>` | Extends the lock validity time |

### Example

```java
RxRedlock rxLock = manager.createRxLock("rx-resource");

rxLock.tryLockSingle(Duration.ofSeconds(5))
rxLock.tryLockRx(Duration.ofSeconds(5))
.flatMapCompletable(acquired -> {
if (acquired) {
return performReactiveWork()
.andThen(rxLock.unlockCompletable());
.andThen(rxLock.unlockRx());
}
return Completable.complete();
})
Expand All @@ -107,8 +118,8 @@ Monitor lock validity in real-time:

```java
rxLock.validityObservable(Duration.ofSeconds(1))
.subscribe(remainingMs -> {
if (remainingMs < 5000) {
.subscribe(remaining -> {
if (remaining.toMillis() < 5000) {
System.out.println("Warning: Lock expiring soon!");
}
});
Expand All @@ -127,7 +138,7 @@ AsyncRedlockImpl combinedLock = manager.createAsyncRxLock("combined-resource");
combinedLock.tryLockAsync().thenAccept(acquired -> { ... });

// Use as RxJava
combinedLock.tryLockSingle().subscribe(acquired -> { ... });
combinedLock.tryLockRx().subscribe(acquired -> { ... });
```

---
Expand All @@ -148,7 +159,7 @@ asyncLock.tryLockAsync()
});

// RxJava auto-renewal
rxLock.tryLockSingle()
rxLock.tryLockRx()
.flatMapCompletable(acquired -> {
if (acquired) {
return longRunningReactiveOperation();
Expand Down Expand Up @@ -177,7 +188,7 @@ asyncLock.tryLockAsync()
### RxJava

```java
rxLock.tryLockSingle()
rxLock.tryLockRx()
.onErrorReturn(ex -> {
logger.error("Lock failed", ex);
return false;
Expand Down
Loading
Loading