Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NATS JetStream support #2257

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Added warnings to some usecases and updated readme
Saphri committed Nov 19, 2024
commit 2d5b43ef1a9501ea45947acee54782ef7d167859
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -887,12 +887,25 @@ public LockProvider lockProvider(DatabaseClient databaseClient) {
```

#### JetStream
NatsJetStreamLockProvider has some limitations due to how NATS have implemented TTL.
TTL is currently defined on 'bucket' level, meaning a lockname cannot have multiple lock timings.
Also 100ms is the smallest lock timing supported. Reaping the TTL expired locks cannot be configured in NATS currently,
so timing is best effort.
NatsJetStreamLockProvider has some limitations due to how NATS have implemented TTL, but its still useful for most usecases.

Buckets are auto created, but never deleted. So any timing changes will require manual deletion of the bucket.
100ms is the smallest lock timing NATS support (currently NatsJetStreamLockProvider will silently increase the values below this to 100ms). Reaper timings of TTL expired locks cannot be configured in NATS currently, so timing is best effort.

Support for LockAtLeastFor is not implemented. NatsJetStreamLockProvider will trigger log warning if this setting is used.

TTL is currently defined on 'bucket' level, meaning a lockname is fixed to a TTL when first encountered. So avoid using the same lockname with different timing settings.

Dont do:
@SchedulerLock(name = "scheduledTaskName", lockAtMostFor = "5m")
.. (somewhere else)
@SchedulerLock(name = "scheduledTaskName", lockAtMostFor = "10m")

But instead you can do:
@SchedulerLock(name = "scheduledTaskName-5m", lockAtMostFor = "5m")
.. (somewhere else)
@SchedulerLock(name = "scheduledTaskName-10m", lockAtMostFor = "10m")

Buckets are auto created with fixed TTL, but never deleted. So any timing changes will require manual deletion of the bucket. NatsJetStreamLockProvider will trigger log warning if this mismatch is detected.

NATS 2.11 should make it possible to define TTL on key level when released... so fingers crossed :D

Original file line number Diff line number Diff line change
@@ -42,6 +42,9 @@ public Optional<SimpleLock> lock(@NonNull LockConfiguration lockConfiguration) {
var bucketName = String.format("SHEDLOCK-%s", lockConfiguration.getName());
log.debug("Attempting lock for bucketName: {}", bucketName);
try {
if (!lockConfiguration.getLockAtLeastFor().isZero()) {
log.warn("lockAtLeastFor does not work with this NatsJetStreamLockProvider. So this setting is ignored!");
}
var lockTime = lockConfiguration.getLockAtMostFor();

// nats cannot accept below 100ms
@@ -59,9 +62,12 @@ public Optional<SimpleLock> lock(@NonNull LockConfiguration lockConfiguration) {

return Optional.of(new NatsJetStreamLock(connection, lockConfiguration));
} catch (JetStreamApiException e) {
if (e.getApiErrorCode() == 10058 || e.getApiErrorCode() == 10071) {
if (e.getApiErrorCode() == 10071) {
log.debug("Rejected lock for bucketName: {}, message: {}", bucketName, e.getMessage());
return Optional.empty();
} else if(e.getApiErrorCode() == 10058) {
log.warn("Settings on the bucket TTL does not match configuration. Manually delete the bucket on NATS server, or revert lock settings!");
return Optional.empty();
}
log.warn("Rejected lock for bucketName: {}", bucketName);
throw new IllegalStateException(e);