Skip to content

Commit

Permalink
ARTEMIS-4332 Add store operation trackers
Browse files Browse the repository at this point in the history
  • Loading branch information
brusdev authored and clebertsuconic committed Jul 13, 2023
1 parent 187ae9d commit b4230c6
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import org.apache.activemq.artemis.core.persistence.OperationContext;
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
import org.apache.activemq.artemis.utils.ExecutorFactory;
import org.apache.commons.collections.Buffer;
import org.apache.commons.collections.BufferUtils;
import org.apache.commons.collections.buffer.CircularFifoBuffer;

/**
* Each instance of OperationContextImpl is associated with an executor (usually an ordered Executor).
Expand All @@ -38,6 +41,9 @@
* If there are no pending IO operations, the tasks are just executed at the callers thread without any context switch.
*
* So, if you are doing operations that are not dependent on IO (e.g NonPersistentMessages) you wouldn't have any context switch.
*
* If you need to track store operations you can set the system property "ARTEMIS_OPCONTEXT_MAX_DEBUG_TRACKERS"
* with the max number of trackers that you want to keep in memory.
*/
public class OperationContextImpl implements OperationContext {

Expand Down Expand Up @@ -104,6 +110,24 @@ public static void setContext(final OperationContext context) {

private final Executor executor;

private static int maxDebugTrackers = Integer.parseInt(
System.getProperty("ARTEMIS_OPCONTEXT_MAX_DEBUG_TRACKERS", "0"));

private Buffer debugTrackers = OperationContextImpl.maxDebugTrackers > 0 ?
BufferUtils.synchronizedBuffer(new CircularFifoBuffer(OperationContextImpl.maxDebugTrackers)) : null;

protected static int getMaxDebugTrackers() {
return OperationContextImpl.maxDebugTrackers;
}

protected static void setMaxDebugTrackers(int maxDebugTrackers) {
OperationContextImpl.maxDebugTrackers = maxDebugTrackers;
}

protected Buffer getDebugTrackers() {
return debugTrackers;
}

public OperationContextImpl(final Executor executor) {
super();
this.executor = executor;
Expand All @@ -122,7 +146,10 @@ public synchronized void pageSyncDone() {

@Override
public void storeLineUp() {
STORE_LINEUP_UPDATER.incrementAndGet(this);
long storeLineUpValue = STORE_LINEUP_UPDATER.incrementAndGet(this);
if (debugTrackers != null) {
debugTrackers.add(new Exception(">" + storeLineUpValue));
}
}

@Override
Expand Down Expand Up @@ -216,7 +243,12 @@ private boolean validateTasksAdd(long storeLined, long replicationLined, long pa

@Override
public synchronized void done() {
stored++;
this.stored++;

if (debugTrackers != null) {
debugTrackers.add(new Exception("<" + stored));
}

checkTasks();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,4 +422,45 @@ public void onError(final int errorCode, final String errorMessage) {
Assert.assertEquals(0, operations.get());
}

@Test
public void testContextWithoutDebugTrackers() {
ExecutorService executor = Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory(getClass().getName()));
runAfter(executor::shutdownNow);

Assert.assertEquals(0, OperationContextImpl.getMaxDebugTrackers());
OperationContextImpl context = new OperationContextImpl(executor);
Assert.assertNull(context.getDebugTrackers());

context.storeLineUp();
Assert.assertNull(context.getDebugTrackers());

context.done();
Assert.assertNull(context.getDebugTrackers());
}

@Test
public void testContextWithDebugTrackers() {
int maxStoreOperationTrackers = OperationContextImpl.getMaxDebugTrackers();
ExecutorService executor = Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory(getClass().getName()));
runAfter(executor::shutdownNow);

OperationContextImpl.setMaxDebugTrackers(1);
try {
Assert.assertEquals(1, OperationContextImpl.getMaxDebugTrackers());
OperationContextImpl context = new OperationContextImpl(executor);
Assert.assertNotNull(context.getDebugTrackers());

context.storeLineUp();
Assert.assertEquals(1, context.getDebugTrackers().size());
Assert.assertEquals("storeLineUp", ((Exception)context.getDebugTrackers().get()).getStackTrace()[0].getMethodName());
Assert.assertEquals("testContextWithDebugTrackers", ((Exception)context.getDebugTrackers().get()).getStackTrace()[1].getMethodName());

context.done();
Assert.assertEquals(1, context.getDebugTrackers().size());
Assert.assertEquals("done", ((Exception)context.getDebugTrackers().get()).getStackTrace()[0].getMethodName());
Assert.assertEquals("testContextWithDebugTrackers", ((Exception)context.getDebugTrackers().get()).getStackTrace()[1].getMethodName());
} finally {
OperationContextImpl.setMaxDebugTrackers(maxStoreOperationTrackers);
}
}
}

0 comments on commit b4230c6

Please sign in to comment.