use of org.apache.activemq.artemis.core.io.buffer.TimedBuffer in project activemq-artemis by apache.
the class TimedBufferTest method testFillBuffer.
@Test
public void testFillBuffer() {
final ArrayList<ByteBuffer> buffers = new ArrayList<>();
final AtomicInteger flushTimes = new AtomicInteger(0);
class TestObserver implements TimedBufferObserver {
@Override
public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks) {
buffers.add(buffer);
flushTimes.incrementAndGet();
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.utils.timedbuffer.TimedBufferObserver#newBuffer(int, int)
*/
@Override
public ByteBuffer newBuffer(final int minSize, final int maxSize) {
return ByteBuffer.allocate(maxSize);
}
@Override
public int getRemainingBytes() {
return 1024 * 1024;
}
}
TimedBuffer timedBuffer = new TimedBuffer(null, 100, TimedBufferTest.ONE_SECOND_IN_NANOS, false);
timedBuffer.start();
try {
timedBuffer.setObserver(new TestObserver());
int x = 0;
for (int i = 0; i < 10; i++) {
byte[] bytes = new byte[10];
for (int j = 0; j < 10; j++) {
bytes[j] = ActiveMQTestBase.getSamplebyte(x++);
}
ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(bytes);
timedBuffer.checkSize(10);
timedBuffer.addBytes(buff, false, dummyCallback);
}
timedBuffer.checkSize(1);
Assert.assertEquals(1, flushTimes.get());
ByteBuffer flushedBuffer = buffers.get(0);
Assert.assertEquals(100, flushedBuffer.limit());
Assert.assertEquals(100, flushedBuffer.capacity());
flushedBuffer.rewind();
for (int i = 0; i < 100; i++) {
Assert.assertEquals(ActiveMQTestBase.getSamplebyte(i), flushedBuffer.get());
}
} finally {
timedBuffer.stop();
}
}
use of org.apache.activemq.artemis.core.io.buffer.TimedBuffer in project activemq-artemis by apache.
the class TimedBufferTest method testTimeOnTimedBuffer.
@Test
public void testTimeOnTimedBuffer() throws Exception {
final ReusableLatch latchFlushed = new ReusableLatch(0);
final AtomicInteger flushes = new AtomicInteger(0);
class TestObserver implements TimedBufferObserver {
@Override
public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks) {
for (IOCallback callback : callbacks) {
callback.done();
}
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.utils.timedbuffer.TimedBufferObserver#newBuffer(int, int)
*/
@Override
public ByteBuffer newBuffer(final int minSize, final int maxSize) {
return ByteBuffer.allocate(maxSize);
}
@Override
public int getRemainingBytes() {
return 1024 * 1024;
}
}
TimedBuffer timedBuffer = new TimedBuffer(null, 100, TimedBufferTest.ONE_SECOND_IN_NANOS / 2, false);
timedBuffer.start();
TestObserver observer = new TestObserver();
timedBuffer.setObserver(observer);
int x = 0;
byte[] bytes = new byte[10];
for (int j = 0; j < 10; j++) {
bytes[j] = ActiveMQTestBase.getSamplebyte(x++);
}
ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(bytes);
IOCallback callback = new IOCallback() {
@Override
public void done() {
System.out.println("done");
latchFlushed.countDown();
}
@Override
public void onError(int errorCode, String errorMessage) {
}
};
try {
latchFlushed.setCount(2);
// simulating a low load period
timedBuffer.addBytes(buff, true, callback);
Thread.sleep(1000);
timedBuffer.addBytes(buff, true, callback);
Assert.assertTrue(latchFlushed.await(5, TimeUnit.SECONDS));
latchFlushed.setCount(5);
flushes.set(0);
// Sending like crazy... still some wait (1 millisecond) between each send..
long time = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
timedBuffer.addBytes(buff, true, callback);
Thread.sleep(1);
}
Assert.assertTrue(latchFlushed.await(5, TimeUnit.SECONDS));
// The purpose of the timed buffer is to batch writes up to a millisecond.. or up to the size of the buffer.
Assert.assertTrue("Timed Buffer is not batching accordingly, it was expected to take at least 500 seconds batching multiple writes while it took " + (System.currentTimeMillis() - time) + " milliseconds", System.currentTimeMillis() - time >= 450);
// ^^ there are some discounts that can happen inside the timed buffer that are still considered valid (like discounting the time it took to perform the operation itself
// for that reason the test has been failing (before this commit) at 499 or 480 milliseconds. So, I'm using a reasonable number close to 500 milliseconds that would still be valid for the test
// it should be in fact only writing once..
// i will set for 3 just in case there's a GC or anything else happening on the test
Assert.assertTrue("Too many writes were called", flushes.get() <= 3);
} finally {
timedBuffer.stop();
}
}
use of org.apache.activemq.artemis.core.io.buffer.TimedBuffer in project activemq-artemis by apache.
the class TimedBufferTest method timeoutShouldMatchFlushIOPSWithNotBlockingFlush.
/**
* This test is showing the behaviour of the TimedBuffer with a blocking API (NIO/MAPPED) and
* how the timeout value is not == 1/IOPS like the ASYNCIO case
*/
@Test
public void timeoutShouldMatchFlushIOPSWithNotBlockingFlush() {
// use a large timeout in order to be reactive
final long timeout = TimeUnit.MILLISECONDS.toNanos(100);
assert ((int) timeout) > 0;
// it is optimistic: the timeout and the blockingDeviceFlushTime are a perfect match
final long deviceTime = timeout;
final int bufferSize = Env.osPageSize();
final TimedBuffer timedBuffer = new TimedBuffer(null, bufferSize, (int) timeout, false);
timedBuffer.start();
try (NonBlockingObserver observer = new NonBlockingObserver(bufferSize, deviceTime)) {
timedBuffer.setObserver(observer);
// do not call checkSize because we already know that will succeed
timedBuffer.addBytes(LONG_ENCODER, true, DummyCallback.getInstance());
// wait the first flush to happen
observer.waitUntilFlushIsDone(1);
// for a not-blocking flush I'm expecting the TimedBuffer has near to finished sleeping now
assert observer.flushesDone() == 1;
// issue a new write
timedBuffer.addBytes(LONG_ENCODER, true, DummyCallback.getInstance());
// the countdown on the TimedBuffer is already started even before this addBytes
final long endOfWriteRequest = System.nanoTime();
// wait until it will succeed
observer.waitUntilFlushIsDone(2);
final long flushDone = System.nanoTime();
final long elapsedTime = flushDone - endOfWriteRequest;
assert observer.flushesDone() == 2;
// it is much more than what is expected!!if it will fail it means that the timed IOPS = 1/(timeout + blockingDeviceFlushTime)!!!!!!
// while it has to be IOPS = 1/timeout
System.out.println("elapsed time: " + elapsedTime + " with timeout: " + timeout);
final long maxExpected = timeout + deviceTime;
Assert.assertTrue("elapsed = " + elapsedTime + " max expected = " + maxExpected, elapsedTime <= maxExpected);
} finally {
timedBuffer.stop();
}
}
use of org.apache.activemq.artemis.core.io.buffer.TimedBuffer in project activemq-artemis by apache.
the class TimedBufferTest method testTimingAndFlush.
@Test
public void testTimingAndFlush() throws Exception {
final ArrayList<ByteBuffer> buffers = new ArrayList<>();
final AtomicInteger flushTimes = new AtomicInteger(0);
class TestObserver implements TimedBufferObserver {
@Override
public void flushBuffer(final ByteBuffer buffer, final boolean sync, final List<IOCallback> callbacks) {
buffers.add(buffer);
flushTimes.incrementAndGet();
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.utils.timedbuffer.TimedBufferObserver#newBuffer(int, int)
*/
@Override
public ByteBuffer newBuffer(final int minSize, final int maxSize) {
return ByteBuffer.allocate(maxSize);
}
@Override
public int getRemainingBytes() {
return 1024 * 1024;
}
}
TimedBuffer timedBuffer = new TimedBuffer(null, 100, TimedBufferTest.ONE_SECOND_IN_NANOS / 10, false);
timedBuffer.start();
try {
timedBuffer.setObserver(new TestObserver());
int x = 0;
byte[] bytes = new byte[10];
for (int j = 0; j < 10; j++) {
bytes[j] = ActiveMQTestBase.getSamplebyte(x++);
}
ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(bytes);
timedBuffer.checkSize(10);
timedBuffer.addBytes(buff, false, dummyCallback);
Thread.sleep(200);
Assert.assertEquals(0, flushTimes.get());
bytes = new byte[10];
for (int j = 0; j < 10; j++) {
bytes[j] = ActiveMQTestBase.getSamplebyte(x++);
}
buff = ActiveMQBuffers.wrappedBuffer(bytes);
timedBuffer.checkSize(10);
timedBuffer.addBytes(buff, true, dummyCallback);
Thread.sleep(500);
Assert.assertEquals(1, flushTimes.get());
ByteBuffer flushedBuffer = buffers.get(0);
Assert.assertEquals(20, flushedBuffer.limit());
Assert.assertEquals(20, flushedBuffer.capacity());
flushedBuffer.rewind();
for (int i = 0; i < 20; i++) {
Assert.assertEquals(ActiveMQTestBase.getSamplebyte(i), flushedBuffer.get());
}
} finally {
timedBuffer.stop();
}
}
use of org.apache.activemq.artemis.core.io.buffer.TimedBuffer in project activemq-artemis by apache.
the class TimedBufferTest method timeoutShouldMatchFlushIOPSWithBlockingFlush.
/**
* This test is showing the behaviour of the TimedBuffer with a blocking API (NIO/MAPPED) and
* how the timeout value is not == 1/IOPS like the ASYNCIO case
*/
@Test
public void timeoutShouldMatchFlushIOPSWithBlockingFlush() {
// use a large timeout in order to be reactive
final long timeout = TimeUnit.MILLISECONDS.toNanos(100);
assert ((int) timeout) > 0;
// it is optimistic: the timeout and the blockingDeviceFlushTime are a perfect match
final long deviceTime = timeout;
final int bufferSize = Env.osPageSize();
final TimedBuffer timedBuffer = new TimedBuffer(null, bufferSize, (int) timeout, false);
timedBuffer.start();
try (BlockingObserver observer = new BlockingObserver(bufferSize, deviceTime)) {
timedBuffer.setObserver(observer);
// do not call checkSize because we already know that will succeed
timedBuffer.addBytes(LONG_ENCODER, true, DummyCallback.getInstance());
// wait the first flush to happen
observer.waitUntilFlushIsDone(1);
// for a blocking flush I'm expecting the TimedBuffer has started sleeping now
assert observer.flushesDone() == 1;
// issue a new write
timedBuffer.addBytes(LONG_ENCODER, true, DummyCallback.getInstance());
// the countdown on the TimedBuffer is already started even before this addBytes
final long endOfWriteRequest = System.nanoTime();
// wait until it will succeed
observer.waitUntilFlushIsDone(2);
final long flushDone = System.nanoTime();
final long elapsedTime = flushDone - endOfWriteRequest;
assert observer.flushesDone() == 2;
// it is much more than what is expected!!if it will fail it means that the timed IOPS = 1/(timeout + blockingDeviceFlushTime)!!!!!!
// while it has to be IOPS = 1/timeout
System.out.println("elapsed time: " + elapsedTime + " with timeout: " + timeout);
final long maxExpected = timeout + deviceTime;
Assert.assertTrue("elapsed = " + elapsedTime + " max expected = " + maxExpected, elapsedTime <= maxExpected);
} finally {
timedBuffer.stop();
}
}
Aggregations