aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2012-12-14 18:27:29 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2012-12-14 18:27:29 +0100
commitaf07212b764549c16cd252a9311bb68c642e8179 (patch)
tree2276df7ea25c510e83da3c70e90d93f75e07e4b2
parent189a12a09eb4fd34b632fb2582eb479e15a08125 (diff)
downloadsonarqube-af07212b764549c16cd252a9311bb68c642e8179.tar.gz
sonarqube-af07212b764549c16cd252a9311bb68c642e8179.zip
SONAR-3887 refactor semaphore API
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java (renamed from sonar-batch/src/main/java/org/sonar/batch/bootstrap/CheckSemaphore.java)43
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectLockTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/bootstrap/CheckSemaphoreTest.java)73
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java34
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/SemaphoresImpl.java (renamed from sonar-core/src/main/java/org/sonar/core/persistence/DatabaseSemaphoreImpl.java)10
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java32
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/SemaphoresImplTest.java (renamed from sonar-core/src/test/java/org/sonar/core/persistence/DatabaseSemaphoreImplTest.java)10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/Semaphores.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/utils/DatabaseSemaphore.java)64
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java2
9 files changed, 134 insertions, 140 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java
index 94448f6f16f..bedc8578223 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java
@@ -48,7 +48,7 @@ import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.metric.CacheMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.persistence.DaoUtils;
-import org.sonar.core.persistence.DatabaseSemaphoreImpl;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.persistence.DatabaseVersion;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.resource.DefaultResourcePermissions;
@@ -104,8 +104,8 @@ public class BatchModule extends Module {
container.addSingleton(DefaultUserFinder.class);
container.addSingleton(ResourceTypes.class);
container.addSingleton(MetricProvider.class);
- container.addSingleton(DatabaseSemaphoreImpl.class);
- container.addSingleton(CheckSemaphore.class);
+ container.addSingleton(SemaphoresImpl.class);
+ container.addSingleton(ProjectLock.class);
}
private void registerDatabaseComponents() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/CheckSemaphore.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java
index 9bc4b65e621..33a4620a4fc 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/CheckSemaphore.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectLock.java
@@ -24,44 +24,42 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Project;
-import org.sonar.api.utils.DatabaseSemaphore;
+import org.sonar.api.utils.Semaphores;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.ProjectTree;
-import static org.sonar.api.utils.DatabaseSemaphore.Lock;
+public class ProjectLock {
-public class CheckSemaphore {
+ private static final Logger LOG = LoggerFactory.getLogger(ProjectLock.class);
- private static final Logger LOG = LoggerFactory.getLogger(CheckSemaphore.class);
-
- private final DatabaseSemaphore databaseSemaphore;
+ private final Semaphores semaphores;
private final ProjectTree projectTree;
private final Settings settings;
- public CheckSemaphore(DatabaseSemaphore databaseSemaphore, ProjectTree projectTree, Settings settings) {
- this.databaseSemaphore = databaseSemaphore;
+ public ProjectLock(Semaphores semaphores, ProjectTree projectTree, Settings settings) {
+ this.semaphores = semaphores;
this.projectTree = projectTree;
this.settings = settings;
}
public void start() {
if (!isInDryRunMode()) {
- Lock lock = acquire();
- if (!lock.isAcquired()) {
- LOG.error(getErrorMessage(lock));
+ Semaphores.Semaphore semaphore = acquire();
+ if (!semaphore.isLocked()) {
+ LOG.error(getErrorMessage(semaphore));
throw new SonarException("The project is already been analysing.");
}
}
}
- private String getErrorMessage(Lock lock) {
- long duration = lock.getDurationSinceLocked();
+ private String getErrorMessage(Semaphores.Semaphore semaphore) {
+ long duration = semaphore.getDurationSinceLocked();
DurationLabel durationLabel = new DurationLabel();
String durationDisplay = durationLabel.label(duration);
- return "It looks like an analysis of '"+ getProject().getName() +"' is already running (started "+ durationDisplay +"). " +
- "If this is not the case, it probably means that previous analysis was interrupted " +
- "and you should then force a re-run by using the option '"+ CoreProperties.FORCE_ANALYSIS +"=true'.";
+ return "It looks like an analysis of '" + getProject().getName() + "' is already running (started " + durationDisplay + "). " +
+ "If this is not the case, it probably means that previous analysis was interrupted " +
+ "and you should then force a re-run by using the option '" + CoreProperties.FORCE_ANALYSIS + "=true'.";
}
public void stop() {
@@ -70,19 +68,18 @@ public class CheckSemaphore {
}
}
- private Lock acquire() {
+ private Semaphores.Semaphore acquire() {
LOG.debug("Acquire semaphore on project : {}, with key {}", getProject(), getSemaphoreKey());
- if (!isForceAnalyseActivated()) {
- return databaseSemaphore.acquire(getSemaphoreKey());
- } else {
+ if (shouldForce()) {
// In force mode, we acquire the lock regardless there's a existing lock or not
- return databaseSemaphore.acquire(getSemaphoreKey(), 0);
+ return semaphores.acquire(getSemaphoreKey(), 0);
}
+ return semaphores.acquire(getSemaphoreKey());
}
private void release() {
LOG.debug("Release semaphore on project : {}, with key {}", getProject(), getSemaphoreKey());
- databaseSemaphore.release(getSemaphoreKey());
+ semaphores.release(getSemaphoreKey());
}
private String getSemaphoreKey() {
@@ -97,7 +94,7 @@ public class CheckSemaphore {
return settings.getBoolean(CoreProperties.DRY_RUN);
}
- private boolean isForceAnalyseActivated() {
+ private boolean shouldForce() {
return settings.getBoolean(CoreProperties.FORCE_ANALYSIS);
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/CheckSemaphoreTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectLockTest.java
index e3d09868d9a..f47061a7c0b 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/CheckSemaphoreTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectLockTest.java
@@ -24,7 +24,7 @@ import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Project;
-import org.sonar.api.utils.DatabaseSemaphore;
+import org.sonar.api.utils.Semaphores;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.ProjectTree;
@@ -32,105 +32,78 @@ import java.util.Date;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
-import static org.sonar.api.utils.DatabaseSemaphore.Lock;
-public class CheckSemaphoreTest {
+public class ProjectLockTest {
- private CheckSemaphore checkSemaphore;
+ private ProjectLock projectLock;
- private DatabaseSemaphore databaseSemaphore;
+ private Semaphores semaphores;
private ProjectTree projectTree;
private Settings settings;
private Project project;
- private Lock lock;
@Before
public void setUp() {
- lock = mock(Lock.class);
-
- databaseSemaphore = mock(DatabaseSemaphore.class);
- when(databaseSemaphore.acquire(anyString())).thenReturn(lock);
- when(databaseSemaphore.acquire(anyString(), anyInt())).thenReturn(lock);
+ semaphores = mock(Semaphores.class);
projectTree = mock(ProjectTree.class);
settings = new Settings();
setDryRunMode(false);
setForceMode(false);
-
- project = new Project("key", "branch", "name");
+ project = new Project("my-project-key");
when(projectTree.getRootProject()).thenReturn(project);
- checkSemaphore = new CheckSemaphore(databaseSemaphore, projectTree, settings);
+ projectLock = new ProjectLock(semaphores, projectTree, settings);
}
@Test
public void shouldAcquireSemaphore() {
- when(lock.isAcquired()).thenReturn(true);
- checkSemaphore.start();
+ when(semaphores.acquire(anyString())).thenReturn(new Semaphores.Semaphore().setLocked(true));
+ projectLock.start();
- verify(databaseSemaphore).acquire(anyString());
- }
-
- @Test
- public void shouldUseProjectKeyInTheKeyOfTheSemaphore() {
- project = new Project("key");
- when(projectTree.getRootProject()).thenReturn(project);
-
- when(lock.isAcquired()).thenReturn(true);
- checkSemaphore.start();
-
- verify(databaseSemaphore).acquire("batch-key");
- }
-
- @Test
- public void shouldUseProjectKeyAndBranchIfExistingInTheKeyOfTheSemaphore() {
- when(lock.isAcquired()).thenReturn(true);
- checkSemaphore.start();
-
- verify(databaseSemaphore).acquire("batch-key:branch");
+ verify(semaphores).acquire("batch-my-project-key");
}
@Test
public void shouldAcquireSemaphoreIfForceAnalyseActivated() {
setForceMode(true);
- when(lock.isAcquired()).thenReturn(true);
- checkSemaphore.start();
- verify(databaseSemaphore).acquire(anyString(), anyInt());
+ when(semaphores.acquire("batch-my-project-key", 0)).thenReturn(new Semaphores.Semaphore().setLocked(true));
+
+ projectLock.start();
}
@Test(expected = SonarException.class)
public void shouldNotAcquireSemaphoreIfTheProjectIsAlreadyBeenAnalysing() {
- when(lock.getLocketAt()).thenReturn(new Date());
- when(lock.isAcquired()).thenReturn(false);
- checkSemaphore.start();
- verify(databaseSemaphore, never()).acquire(anyString());
+ when(semaphores.acquire(anyString())).thenReturn(new Semaphores.Semaphore().setLocked(false).setDurationSinceLocked(1234L));
+ projectLock.start();
}
@Test
public void shouldNotAcquireSemaphoreInDryRunMode() {
setDryRunMode(true);
settings = new Settings().setProperty(CoreProperties.DRY_RUN, true);
- checkSemaphore.start();
- verify(databaseSemaphore, never()).acquire(anyString());
- verify(databaseSemaphore, never()).acquire(anyString(), anyInt());
+ projectLock.start();
+ verifyZeroInteractions(semaphores);
}
@Test
public void shouldReleaseSemaphore() {
- checkSemaphore.stop();
- verify(databaseSemaphore).release(anyString());
+ projectLock.stop();
+ verify(semaphores).release("batch-my-project-key");
}
@Test
public void shouldNotReleaseSemaphoreInDryRunMode() {
setDryRunMode(true);
- checkSemaphore.stop();
- verify(databaseSemaphore, never()).release(anyString());
+ projectLock.stop();
+ verifyZeroInteractions(semaphores);
}
private void setDryRunMode(boolean isInDryRunMode) {
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java
index 471315c2d40..3e36545012b 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoreDao.java
@@ -23,11 +23,10 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.apache.commons.lang.time.DateUtils;
import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.utils.Semaphores;
import java.util.Date;
-import static org.sonar.api.utils.DatabaseSemaphore.Lock;
-
/**
* @since 3.4
*/
@@ -39,7 +38,7 @@ public class SemaphoreDao {
this.mybatis = mybatis;
}
- public Lock acquire(String name, int maxDurationInSeconds) {
+ public Semaphores.Semaphore acquire(String name, int maxDurationInSeconds) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Semaphore name must not be empty");
Preconditions.checkArgument(maxDurationInSeconds >= 0, "Semaphore max duration must be positive: " + maxDurationInSeconds);
@@ -47,7 +46,7 @@ public class SemaphoreDao {
try {
SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class);
Date lockedAt = org.sonar.api.utils.DateUtils.parseDate("2001-01-01");
- createSemaphore(name, lockedAt, session);
+ createDto(name, lockedAt, session);
boolean isAcquired = doAcquire(name, maxDurationInSeconds, session, mapper);
SemaphoreDto semaphore = selectSemaphore(name, session);
return createLock(semaphore, session, isAcquired);
@@ -56,7 +55,7 @@ public class SemaphoreDao {
}
}
- public Lock acquire(String name) {
+ public Semaphores.Semaphore acquire(String name) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Semaphore name must not be empty");
SqlSession session = mybatis.openSession();
@@ -67,7 +66,7 @@ public class SemaphoreDao {
if (semaphore != null) {
return createLock(semaphore, session, false);
} else {
- semaphore = createSemaphore(name, now, session);
+ semaphore = createDto(name, now, session);
return createLock(semaphore, session, true);
}
} finally {
@@ -93,12 +92,12 @@ public class SemaphoreDao {
return ok;
}
- private SemaphoreDto createSemaphore(String name, Date lockedAt, SqlSession session) {
+ private SemaphoreDto createDto(String name, Date lockedAt, SqlSession session) {
try {
SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class);
SemaphoreDto semaphore = new SemaphoreDto()
- .setName(name)
- .setLockedAt(lockedAt);
+ .setName(name)
+ .setLockedAt(lockedAt);
mapper.initialize(semaphore);
session.commit();
return semaphore;
@@ -109,12 +108,17 @@ public class SemaphoreDao {
}
}
- private Lock createLock(SemaphoreDto semaphore, SqlSession session, boolean acquired) {
- Lock lock = new Lock(semaphore.getName(), acquired, semaphore.getLockedAt(), semaphore.getCreatedAt(), semaphore.getUpdatedAt());
+ private Semaphores.Semaphore createLock(SemaphoreDto dto, SqlSession session, boolean acquired) {
+ Semaphores.Semaphore semaphore = new Semaphores.Semaphore()
+ .setName(dto.getName())
+ .setLocked(acquired)
+ .setLocketAt(dto.getLockedAt())
+ .setCreatedAt(dto.getCreatedAt())
+ .setUpdatedAt(dto.getUpdatedAt());
if (!acquired) {
- lock.setDurationSinceLocked(getDurationSinceLocked(semaphore, session));
+ semaphore.setDurationSinceLocked(getDurationSinceLocked(dto, session));
}
- return lock;
+ return semaphore;
}
private long getDurationSinceLocked(SemaphoreDto semaphore, SqlSession session) {
@@ -124,12 +128,12 @@ public class SemaphoreDao {
return now - locketAt;
}
- protected SemaphoreDto selectSemaphore(String name, SqlSession session){
+ protected SemaphoreDto selectSemaphore(String name, SqlSession session) {
SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class);
return mapper.selectSemaphore(name);
}
- protected Date now(SqlSession session){
+ protected Date now(SqlSession session) {
SemaphoreMapper mapper = session.getMapper(SemaphoreMapper.class);
return mapper.now();
}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseSemaphoreImpl.java b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoresImpl.java
index 75a5bb7e2ed..b69cff90448 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseSemaphoreImpl.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/SemaphoresImpl.java
@@ -19,24 +19,24 @@
*/
package org.sonar.core.persistence;
-import org.sonar.api.utils.DatabaseSemaphore;
+import org.sonar.api.utils.Semaphores;
/**
* @since 3.4
*/
-public class DatabaseSemaphoreImpl implements DatabaseSemaphore {
+public class SemaphoresImpl implements Semaphores {
private SemaphoreDao dao;
- public DatabaseSemaphoreImpl(SemaphoreDao dao) {
+ public SemaphoresImpl(SemaphoreDao dao) {
this.dao = dao;
}
- public Lock acquire(String name, int maxDurationInSeconds) {
+ public Semaphore acquire(String name, int maxDurationInSeconds) {
return dao.acquire(name, maxDurationInSeconds);
}
- public Lock acquire(String name) {
+ public Semaphore acquire(String name) {
return dao.acquire(name);
}
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java
index 948afed4a59..ccfcb6336c3 100644
--- a/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoreDaoTest.java
@@ -25,6 +25,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.Semaphores;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
@@ -32,7 +33,6 @@ import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;
import static org.fest.assertions.Assertions.assertThat;
-import static org.sonar.api.utils.DatabaseSemaphore.Lock;
public class SemaphoreDaoTest extends AbstractDaoTestCase {
@@ -75,8 +75,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void create_and_acquire_semaphore() throws Exception {
- Lock lock = dao.acquire("foo", 60);
- assertThat(lock.isAcquired()).isTrue();
+ Semaphores.Semaphore lock = dao.acquire("foo", 60);
+ assertThat(lock.isLocked()).isTrue();
assertThat(lock.getDurationSinceLocked()).isNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -92,8 +92,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void create_and_acquire_semaphore_when_timeout_is_zeo() throws Exception {
- Lock lock = dao.acquire("foo", 0);
- assertThat(lock.isAcquired()).isTrue();
+ Semaphores.Semaphore lock = dao.acquire("foo", 0);
+ assertThat(lock.isLocked()).isTrue();
assertThat(lock.getDurationSinceLocked()).isNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -109,8 +109,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void create_and_acquire_semaphore_when_no_timeout() throws Exception {
- Lock lock = dao.acquire("foo");
- assertThat(lock.isAcquired()).isTrue();
+ Semaphores.Semaphore lock = dao.acquire("foo");
+ assertThat(lock.isLocked()).isTrue();
assertThat(lock.getDurationSinceLocked()).isNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -127,8 +127,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void fail_to_acquire_locked_semaphore() throws Exception {
setupData("old_semaphore");
- Lock lock = dao.acquire("foo", Integer.MAX_VALUE);
- assertThat(lock.isAcquired()).isFalse();
+ Semaphores.Semaphore lock = dao.acquire("foo", Integer.MAX_VALUE);
+ assertThat(lock.isLocked()).isFalse();
assertThat(lock.getDurationSinceLocked()).isNotNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -142,8 +142,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void acquire_long_locked_semaphore() throws Exception {
setupData("old_semaphore");
- Lock lock = dao.acquire("foo", 60);
- assertThat(lock.isAcquired()).isTrue();
+ Semaphores.Semaphore lock = dao.acquire("foo", 60);
+ assertThat(lock.isLocked()).isTrue();
assertThat(lock.getDurationSinceLocked()).isNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -157,8 +157,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void acquire_locked_semaphore_when_timeout_is_zeo() throws Exception {
setupData("old_semaphore");
- Lock lock = dao.acquire("foo", 0);
- assertThat(lock.isAcquired()).isTrue();
+ Semaphores.Semaphore lock = dao.acquire("foo", 0);
+ assertThat(lock.isLocked()).isTrue();
assertThat(lock.getDurationSinceLocked()).isNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -175,8 +175,8 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
@Test
public void fail_to_acquire_locked_semaphore_when_no_timeout() throws Exception {
setupData("old_semaphore");
- Lock lock = dao.acquire("foo");
- assertThat(lock.isAcquired()).isFalse();
+ Semaphores.Semaphore lock = dao.acquire("foo");
+ assertThat(lock.isLocked()).isFalse();
assertThat(lock.getDurationSinceLocked()).isNotNull();
SemaphoreDto semaphore = selectSemaphore("foo");
@@ -259,7 +259,7 @@ public class SemaphoreDaoTest extends AbstractDaoTestCase {
try {
barrier.await();
for (int i = 0; i < 100; i++) {
- if (dao.acquire("my-lock", 60 * 5).isAcquired()) {
+ if (dao.acquire("my-lock", 60 * 5).isLocked()) {
locks.incrementAndGet();
}
}
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/DatabaseSemaphoreImplTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoresImplTest.java
index 73a7d61396b..a09b49a3048 100644
--- a/sonar-core/src/test/java/org/sonar/core/persistence/DatabaseSemaphoreImplTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/persistence/SemaphoresImplTest.java
@@ -20,23 +20,23 @@
package org.sonar.core.persistence;
import org.junit.Test;
+import org.sonar.api.utils.Semaphores;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.sonar.api.utils.DatabaseSemaphore.Lock;
-public class DatabaseSemaphoreImplTest {
+public class SemaphoresImplTest {
@Test
public void should_be_a_bridge_over_dao() {
- Lock lock = mock(Lock.class);
SemaphoreDao dao = mock(SemaphoreDao.class);
- when(dao.acquire(anyString(), anyInt())).thenReturn(lock);
+ Semaphores.Semaphore semaphore = new Semaphores.Semaphore();
+ when(dao.acquire(anyString(), anyInt())).thenReturn(semaphore);
- DatabaseSemaphoreImpl impl = new DatabaseSemaphoreImpl(dao);
+ SemaphoresImpl impl = new SemaphoresImpl(dao);
impl.acquire("do-xxx", 50000);
verify(dao).acquire("do-xxx", 50000);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/DatabaseSemaphore.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Semaphores.java
index 93d8ef9075a..1b3a7116fb2 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/DatabaseSemaphore.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Semaphores.java
@@ -26,82 +26,100 @@ import java.util.Date;
/**
* A semaphore shared among all the processes that can connect to the central database.
+ * It's ignored when enabling the dry run mode.
*
* @since 3.4
*/
-public interface DatabaseSemaphore extends BatchComponent, ServerComponent {
+public interface Semaphores extends BatchComponent, ServerComponent {
/**
- * Try to acquire a lock on a name, for a given duration.
- * The lock will be acquired if there's no existing lock on this name or if a lock exists but the max duration is reached.
+ * Try to acquire a semaphore for a given duration.
+ * The semaphore is acquired if it's unlocked or if the max locking duration is reached.
*
- * @param name the key of the semaphore
- * @param maxDurationInSeconds the max duration in seconds the semaphore will be acquired (a value of zero can be used to always acquire a lock)
- * @return a lock containing information if the lock could be acquired or not, the duration since locked, etc.
+ * @param name the key of the semaphore
+ * @param maxDurationInSeconds the max duration in seconds the semaphore will be acquired. The value zero forces the semaphore to be acquired, whatever its status.
+ * @return the semaphore, whatever its status (locked or unlocked). Can't be null.
*/
- Lock acquire(String name, int maxDurationInSeconds);
+ Semaphore acquire(String name, int maxDurationInSeconds);
/**
- * Try to acquire the lock on a name.
+ * Try to acquire a semaphore.
* The lock will be acquired only if there's no existing lock.
*
* @param name the key of the semaphore
* @return a lock containing information if the lock could be acquired or not, the duration since locked, etc.
*/
- Lock acquire(String name);
+ Semaphore acquire(String name);
/**
- * Release the lock on a semaphore by its name.
+ * Release the lock on a semaphore by its name. Does nothing if the lock is already released.
*
* @param name the key of the semaphore
*/
void release(String name);
- class Lock {
+ class Semaphore {
private String name;
- private boolean acquired;
+ private boolean locked;
private Date locketAt;
private Date createdAt;
private Date updatedAt;
private Long durationSinceLocked;
- public Lock(String name, boolean acquired, Date locketAt, Date createdAt, Date updatedAt) {
+ public String getName() {
+ return name;
+ }
+
+ public Semaphore setName(String name) {
this.name = name;
- this.acquired = acquired;
- this.locketAt = locketAt;
- this.createdAt = createdAt;
- this.updatedAt = updatedAt;
+ return this;
}
- public String getName() {
- return name;
+ public boolean isLocked() {
+ return locked;
+ }
+
+ public Semaphore setLocked(boolean locked) {
+ this.locked = locked;
+ return this;
}
public Date getLocketAt() {
return locketAt;
}
+ public Semaphore setLocketAt(Date locketAt) {
+ this.locketAt = locketAt;
+ return this;
+ }
+
public Date getCreatedAt() {
return createdAt;
}
+ public Semaphore setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
public Date getUpdatedAt() {
return updatedAt;
}
- public boolean isAcquired() {
- return acquired;
+ public Semaphore setUpdatedAt(Date updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
}
public Long getDurationSinceLocked() {
return durationSinceLocked;
}
- public void setDurationSinceLocked(Long durationSinceLocked) {
+ public Semaphore setDurationSinceLocked(Long durationSinceLocked) {
this.durationSinceLocked = durationSinceLocked;
+ return this;
}
-
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 9809d4816c6..eff0770fcf3 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -51,6 +51,7 @@ import org.sonar.core.persistence.DatabaseVersion;
import org.sonar.core.persistence.DefaultDatabase;
import org.sonar.core.persistence.DryRunDatabaseFactory;
import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.qualitymodel.DefaultModelFinder;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.DefaultRuleFinder;
@@ -181,6 +182,7 @@ public final class Platform {
rootContainer.addSingleton(RuleI18nManager.class);
rootContainer.addSingleton(GwtI18n.class);
rootContainer.addSingleton(DryRunDatabaseFactory.class);
+ rootContainer.addSingleton(SemaphoresImpl.class);
rootContainer.startComponents();
}