mirror of
https://github.com/google/nomulus.git
synced 2025-05-15 17:07:15 +02:00
Remove queueing from Lock
It was buggy (didn't work) and was never actually used. Why never actually used: for it to be used executeWithLock has to be called with different requesters on the same lockId. That never happend in the code. How it was buggy: Logically, the queue is deleted on release of the lock (meaning it was meaningless the only time it mattered - when the lock isn't taken). In addition, a different bug meant that having items in the queue prevented the lock from being released forcing all other tasks to have to wait for lock timeout even if the task that acquired the lock is long done. Alternative: fix the queue. This would mean we don't want to delete the lock on release (since we want to keep the queue). Instead, we resave the same lock with expiration date being START_OF_TIME. In addition - we need to fix the .equals used to determine if the lock the same as the acquired lock - instead use some isSame function that ignores the queue. Note: the queue is dangerous! An item (calling class / action) in the first place of a queue means no other calling class can get that lock. Everything is waiting for the first calling class to be re-run - but that might take a long time (depending on that action's rerun policy) and even might never happen (if for some reason that action decided it was no longer needed without acquiring the lock) - causing all other actions to stall forever! ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=163705463
This commit is contained in:
parent
fa858ac5cf
commit
aee4f7acc2
9 changed files with 54 additions and 118 deletions
|
@ -48,65 +48,47 @@ public class LockTest {
|
|||
|
||||
@Test
|
||||
public void testReleasedExplicitly() throws Exception {
|
||||
Lock lock = Lock.acquire(getClass(), RESOURCE_NAME, "", ONE_DAY);
|
||||
Lock lock = Lock.acquire(RESOURCE_NAME, "", ONE_DAY);
|
||||
assertThat(lock).isNotNull();
|
||||
// We can't get it again at the same time.
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "", ONE_DAY)).isNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "", ONE_DAY)).isNull();
|
||||
// But if we release it, it's available.
|
||||
lock.release();
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "", ONE_DAY)).isNotNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "", ONE_DAY)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleasedAfterTimeout() throws Exception {
|
||||
FakeClock clock = new FakeClock();
|
||||
inject.setStaticField(Ofy.class, "clock", clock);
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "", TWO_MILLIS)).isNotNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "", TWO_MILLIS)).isNotNull();
|
||||
// We can't get it again at the same time.
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "", TWO_MILLIS)).isNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "", TWO_MILLIS)).isNull();
|
||||
// A second later we still can't get the lock.
|
||||
clock.advanceOneMilli();
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "", TWO_MILLIS)).isNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "", TWO_MILLIS)).isNull();
|
||||
// But two seconds later we can get it.
|
||||
clock.advanceOneMilli();
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "", TWO_MILLIS)).isNotNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "", TWO_MILLIS)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTldsAreIndependent() throws Exception {
|
||||
Lock lockA = Lock.acquire(getClass(), RESOURCE_NAME, "a", ONE_DAY);
|
||||
Lock lockA = Lock.acquire(RESOURCE_NAME, "a", ONE_DAY);
|
||||
assertThat(lockA).isNotNull();
|
||||
// For a different tld we can still get a lock with the same name.
|
||||
Lock lockB = Lock.acquire(getClass(), RESOURCE_NAME, "b", ONE_DAY);
|
||||
Lock lockB = Lock.acquire(RESOURCE_NAME, "b", ONE_DAY);
|
||||
assertThat(lockB).isNotNull();
|
||||
// We can't get lockB again at the same time.
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "b", ONE_DAY)).isNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "b", ONE_DAY)).isNull();
|
||||
// Releasing lockA has no effect on lockB (even though we are still using the "b" tld).
|
||||
lockA.release();
|
||||
assertThat(Lock.acquire(getClass(), RESOURCE_NAME, "b", ONE_DAY)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueueing() throws Exception {
|
||||
// This should work... there's nothing on the queue.
|
||||
Lock lock = Lock.acquire(String.class, RESOURCE_NAME, "", TWO_MILLIS);
|
||||
assertThat(lock).isNotNull();
|
||||
lock.release();
|
||||
// Queue up a request from "Object".
|
||||
Lock.joinQueue(Object.class, RESOURCE_NAME, "");
|
||||
// We can't get the lock because the "requester" is different than what's on the queue.
|
||||
assertThat(Lock.acquire(String.class, RESOURCE_NAME, "", TWO_MILLIS)).isNull();
|
||||
// But this will work because the requester is the same as what's on the queue.
|
||||
lock = Lock.acquire(Object.class, RESOURCE_NAME, "", TWO_MILLIS);
|
||||
assertThat(lock).isNotNull();
|
||||
lock.release();
|
||||
// Now the queue is empty again so we can get the lock.
|
||||
assertThat(Lock.acquire(String.class, RESOURCE_NAME, "", TWO_MILLIS)).isNotNull();
|
||||
assertThat(Lock.acquire(RESOURCE_NAME, "b", ONE_DAY)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_emptyResourceName() throws Exception {
|
||||
thrown.expect(IllegalArgumentException.class, "resourceName cannot be null or empty");
|
||||
Lock.acquire(String.class, "", "", TWO_MILLIS);
|
||||
Lock.acquire("", "", TWO_MILLIS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue