+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.sonar.ce.async;
import java.util.HashSet;
assertThat(getMBean()).isNull();
}
+ /**
+ * Dumb implementation of CEQueueStatus which returns constant values for get methods and throws UnsupportedOperationException
+ * for other methods.
+ */
+ @CheckForNull
+ private ObjectInstance getMBean() throws Exception {
+ try {
+ return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(CeTasksMBean.OBJECT_NAME));
+ } catch (InstanceNotFoundException e) {
+ return null;
+ }
+ }
+
@Test
public void get_methods_delegate_to_the_CEQueueStatus_instance() {
assertThat(underTest.getPendingCount()).isEqualTo(PENDING_COUNT);
assertThat(section.getName()).isEqualTo("Compute Engine Tasks");
assertThat(section.getAttributesCount()).isEqualTo(7);
}
-
- /**
- * Dumb implementation of CEQueueStatus which returns constant values for get methods and throws UnsupportedOperationException
- * for other methods.
- */
private static class DumbCEQueueStatus implements CEQueueStatus {
+
@Override
public long getPendingCount() {
return PENDING_COUNT;
public long getProcessingTime() {
return PROCESSING_TIME;
}
-
private long methodNotImplemented() {
throw new UnsupportedOperationException("Not Implemented");
}
- }
+ }
private static class DumbCeConfiguration implements CeConfiguration {
+
@Override
public void refresh() {
throw new UnsupportedOperationException("Refresh is not implemented");
}
}
-
- @CheckForNull
- private ObjectInstance getMBean() throws Exception {
- try {
- return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(CeTasksMBean.OBJECT_NAME));
- } catch (InstanceNotFoundException e) {
- return null;
- }
- }
}
package org.sonar.server.async;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import org.sonar.api.utils.log.Logger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class AsyncExecutionExecutorServiceImpl
- extends AbstractStoppableExecutorService<ExecutorService>
- implements AsyncExecutionExecutorService {
+ extends AbstractStoppableExecutorService<ThreadPoolExecutor>
+ implements AsyncExecutionExecutorService, AsyncExecutionMonitoring {
private static final Logger LOG = Loggers.get(AsyncExecutionExecutorServiceImpl.class);
private static final int MIN_THREAD_COUNT = 1;
public void addToQueue(Runnable r) {
this.submit(r);
}
+
+ @Override
+ public int getQueueSize() {
+ return delegate.getQueue().size();
+ }
+
+ @Override
+ public int getWorkerCount() {
+ return delegate.getPoolSize();
+ }
+
+ @Override
+ public int getLargestWorkerCount() {
+ return delegate.getLargestPoolSize();
+ }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.async;
+
+public interface AsyncExecutionMBean {
+
+ String OBJECT_NAME = "SonarQube:name=AsyncExecution";
+
+ long getQueueSize();
+
+ long getWorkerCount();
+
+ long getLargestWorkerCount();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.async;
+
+import org.picocontainer.Startable;
+import org.sonar.process.Jmx;
+
+public class AsyncExecutionMBeanImpl implements AsyncExecutionMBean, Startable {
+
+ private final AsyncExecutionMonitoring asyncExecutionMonitoring;
+
+ public AsyncExecutionMBeanImpl(AsyncExecutionMonitoring asyncExecutionMonitoring) {
+ this.asyncExecutionMonitoring = asyncExecutionMonitoring;
+ }
+
+ @Override
+ public void start() {
+ Jmx.register(OBJECT_NAME, this);
+ }
+
+ @Override
+ public void stop() {
+ Jmx.unregister(OBJECT_NAME);
+ }
+
+ @Override
+ public long getQueueSize() {
+ return asyncExecutionMonitoring.getQueueSize();
+ }
+
+ @Override
+ public long getWorkerCount() {
+ return asyncExecutionMonitoring.getWorkerCount();
+ }
+
+ @Override
+ public long getLargestWorkerCount() {
+ return asyncExecutionMonitoring.getLargestWorkerCount();
+ }
+}
@Override
protected void configureModule() {
add(
+ AsyncExecutionMBeanImpl.class,
AsyncExecutionExecutorServiceImpl.class,
AsyncExecutionImpl.class);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.async;
+
+public interface AsyncExecutionMonitoring {
+ int getQueueSize();
+
+ int getWorkerCount();
+
+ int getLargestWorkerCount();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.async;
+
+import java.lang.management.ManagementFactory;
+import javax.annotation.CheckForNull;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class AsyncExecutionMBeanImplTest {
+ private AsyncExecutionMonitoring asyncExecutionMonitoring = Mockito.mock(AsyncExecutionMonitoring.class);
+
+ private AsyncExecutionMBeanImpl underTest = new AsyncExecutionMBeanImpl(asyncExecutionMonitoring);
+
+ @Test
+ public void register_and_unregister() throws Exception {
+ assertThat(getMBean()).isNull();
+
+ underTest.start();
+ assertThat(getMBean()).isNotNull();
+
+ underTest.stop();
+ assertThat(getMBean()).isNull();
+ }
+
+ @Test
+ public void getQueueSize_delegates_to_AsyncExecutionMonitoring() {
+ when(asyncExecutionMonitoring.getQueueSize()).thenReturn(12);
+
+ assertThat(underTest.getQueueSize()).isEqualTo(12);
+
+ verify(asyncExecutionMonitoring).getQueueSize();
+ }
+
+ @Test
+ public void getWorkerCount_delegates_to_AsyncExecutionMonitoring() {
+ when(asyncExecutionMonitoring.getWorkerCount()).thenReturn(12);
+
+ assertThat(underTest.getWorkerCount()).isEqualTo(12);
+
+ verify(asyncExecutionMonitoring).getWorkerCount();
+ }
+
+ @Test
+ public void getLargestWorkerCount_delegates_to_AsyncExecutionMonitoring() {
+ when(asyncExecutionMonitoring.getLargestWorkerCount()).thenReturn(12);
+
+ assertThat(underTest.getLargestWorkerCount()).isEqualTo(12);
+
+ verify(asyncExecutionMonitoring).getLargestWorkerCount();
+ }
+
+ @CheckForNull
+ private ObjectInstance getMBean() throws Exception {
+ try {
+ return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(AsyncExecutionMBean.OBJECT_NAME));
+ } catch (InstanceNotFoundException e) {
+ return null;
+ }
+ }
+
+
+}