KubernetesLock#lockInterruptibly()
This commit is contained in:
committed by
Ioannis Canellos
parent
52e82796ba
commit
7e92d8a03a
@@ -22,7 +22,7 @@ import java.util.concurrent.locks.Lock;
|
||||
|
||||
public class KubernetesLock implements Lock {
|
||||
|
||||
private static final int RETRY_PERIOD = 100;
|
||||
private static final int LOCK_RETRY_INTERVAL = 100;
|
||||
|
||||
private final ConfigMapLockRepository repository;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class KubernetesLock implements Lock {
|
||||
if (repository.create(name, holder, expiration)) {
|
||||
return;
|
||||
}
|
||||
Thread.sleep(RETRY_PERIOD);
|
||||
Thread.sleep(LOCK_RETRY_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
// This method cannot be interrupted
|
||||
}
|
||||
@@ -56,7 +56,18 @@ public class KubernetesLock implements Lock {
|
||||
|
||||
@Override
|
||||
public void lockInterruptibly() throws InterruptedException {
|
||||
// TODO same as lock(), but thread can be interrupted
|
||||
repository.deleteIfExpired(name);
|
||||
while (true) {
|
||||
try {
|
||||
if (repository.create(name, holder, expiration)) {
|
||||
return;
|
||||
}
|
||||
Thread.sleep(LOCK_RETRY_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,15 +33,8 @@ public class KubernetesLockTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldWaitUntilLockCanBeAcquired() {
|
||||
given(repository.create(NAME, HOLDER, 0)).will(new Answer<Boolean>() {
|
||||
private int callsCounter = 0;
|
||||
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocationOnMock) {
|
||||
return callsCounter++ > 0;
|
||||
}
|
||||
});
|
||||
public void lockShouldWaitUntilLockCanBeAcquired() {
|
||||
given(repository.create(NAME, HOLDER, 0)).will(new LockInSecondCall());
|
||||
|
||||
KubernetesLock lock = new KubernetesLock(repository, NAME, HOLDER, 0);
|
||||
lock.lock();
|
||||
@@ -52,17 +45,7 @@ public class KubernetesLockTest {
|
||||
|
||||
@Test
|
||||
public void lockShouldNotBeInterrupted() {
|
||||
given(repository.create(NAME, HOLDER, 0)).will(new Answer<Boolean>() {
|
||||
private int callsCounter = 0;
|
||||
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocationOnMock) throws InterruptedException {
|
||||
if (callsCounter++ > 0) {
|
||||
return true;
|
||||
}
|
||||
throw new InterruptedException("test exception");
|
||||
}
|
||||
});
|
||||
given(repository.create(NAME, HOLDER, 0)).will(new InterrupFirstCall());
|
||||
|
||||
KubernetesLock lock = new KubernetesLock(repository, NAME, HOLDER, 0);
|
||||
lock.lock();
|
||||
@@ -72,13 +55,33 @@ public class KubernetesLockTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLockWithLockInterruptibly() {
|
||||
public void shouldLockWithLockInterruptibly() throws InterruptedException {
|
||||
given(repository.create(NAME, HOLDER, 0)).willReturn(true);
|
||||
|
||||
KubernetesLock lock = new KubernetesLock(repository, NAME, HOLDER, 0);
|
||||
lock.lockInterruptibly();
|
||||
|
||||
verify(repository).deleteIfExpired(NAME);
|
||||
verify(repository).create(NAME, HOLDER, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lockInterruptiblyShouldBeInterrupted() {
|
||||
public void lockInterruptiblyShouldWaitUntilLockCanBeAcquired() throws InterruptedException {
|
||||
given(repository.create(NAME, HOLDER, 0)).will(new LockInSecondCall());
|
||||
|
||||
KubernetesLock lock = new KubernetesLock(repository, NAME, HOLDER, 0);
|
||||
lock.lockInterruptibly();
|
||||
|
||||
verify(repository).deleteIfExpired(NAME);
|
||||
verify(repository, times(2)).create(NAME, HOLDER, 0);
|
||||
}
|
||||
|
||||
@Test(expected = InterruptedException.class)
|
||||
public void lockInterruptiblyShouldBeInterrupted() throws InterruptedException {
|
||||
given(repository.create(NAME, HOLDER, 0)).will(new InterrupFirstCall());
|
||||
|
||||
KubernetesLock lock = new KubernetesLock(repository, NAME, HOLDER, 0);
|
||||
lock.lockInterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -107,4 +110,25 @@ public class KubernetesLockTest {
|
||||
lock.newCondition();
|
||||
}
|
||||
|
||||
private static class LockInSecondCall implements Answer<Boolean> {
|
||||
private int callsCounter = 0;
|
||||
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocationOnMock) {
|
||||
return callsCounter++ > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class InterrupFirstCall implements Answer<Boolean> {
|
||||
private int callsCounter = 0;
|
||||
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocationOnMock) throws InterruptedException {
|
||||
if (callsCounter++ > 0) {
|
||||
return true;
|
||||
}
|
||||
throw new InterruptedException("test exception");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user