/** * Synchronous 'next' * @param id sequencer id * @param wrapAt wrap at value * @return next sequencer value */ public long next (String id, long wrapAt) { return getOrCreate(id).next(wrapAt); }
/** * Reset an async lock * @param id lock ID * @param lockedBy unique client identifier * @param value new sequencer value * @param release if true, lock is released after reset * @throws LockTimeoutException if lock can't be obtained after 'timeout' has elapsed */ public void reset (String id, long lockedBy, long value, boolean release) { lock(id, lockedBy, 0L, 1000L, seq -> { seq.setValue(0L); if (release) seq.setLockedBy(0L); return 0L; }); }
SeqNo seq = getOrCreate(id); long now = System.currentTimeMillis(); if (seq.getLockedBy() == 0 || seq.getLockedBy() == lockedBy || seq.getLockUntil() < now) { seq.setLockedBy(lockedBy); seq.setLockUntil(now + lockTimeout); long l = action.apply(seq); db1.commit();
/** * Release an async lock * @param id lock ID * @param lockedBy unique client identifier */ public boolean release (String id, long lockedBy) { if (db.session != null && db.session.isOpen()) throw new IllegalStateException("DB should not be open"); try (DB db1 = db) { db1.open(); db1.beginTransaction(); SeqNo seq = getOrCreate(id); if (seq.getLockedBy() == lockedBy && seq.getLockUntil() > System.currentTimeMillis()) { seq.setLockedBy(0L); db1.commit(); return true; } } return false; }
/** * Synchronous 'reset' * @param id sequencer id * @param value reset value */ public void reset (String id, long value) { getOrCreate(id).setValue(value); }
private void create (String id) { try (DB db = new DB()) { db.open(); db.beginTransaction(); SeqNo seq = new SeqNo(id); db.session().save(seq); db.commit(); } catch (Exception ignored) { } } }
/** * Asynchronous 'next' * * @param id sequencer ID * @param lockedBy unique client identifier (any long, has to be system-wide unique) * @param lockTimeout once lock is obtained, keep it fo 'lockTimeout' millis (if not 'released' earlier) * @param timeout time (in millis) to wait for this lock * @param wrapAt wrap at value * @return next sequencer value * @throws LockTimeoutException if lock can't be obtained after 'timeout' has elapsed */ public long next (String id, long lockedBy, long lockTimeout, long timeout, long wrapAt) { return lock (id, lockedBy, lockTimeout, timeout, seq -> seq.next(wrapAt)); }