Search in sources :

Example 1 with TimedBuffer

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();
    }
}
Also used : TimedBufferObserver(org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver) TimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ByteBuffer(java.nio.ByteBuffer) ActiveMQBuffer(org.apache.activemq.artemis.api.core.ActiveMQBuffer) Test(org.junit.Test)

Example 2 with TimedBuffer

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();
    }
}
Also used : TimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer) ByteBuffer(java.nio.ByteBuffer) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) TimedBufferObserver(org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver) ReusableLatch(org.apache.activemq.artemis.utils.ReusableLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) List(java.util.List) ActiveMQBuffer(org.apache.activemq.artemis.api.core.ActiveMQBuffer) Test(org.junit.Test)

Example 3 with TimedBuffer

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();
    }
}
Also used : TimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer) Test(org.junit.Test)

Example 4 with TimedBuffer

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();
    }
}
Also used : TimedBufferObserver(org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver) TimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ByteBuffer(java.nio.ByteBuffer) ActiveMQBuffer(org.apache.activemq.artemis.api.core.ActiveMQBuffer) Test(org.junit.Test)

Example 5 with TimedBuffer

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();
    }
}
Also used : TimedBuffer(org.apache.activemq.artemis.core.io.buffer.TimedBuffer) Test(org.junit.Test)

Aggregations

TimedBuffer (org.apache.activemq.artemis.core.io.buffer.TimedBuffer)5 Test (org.junit.Test)5 ByteBuffer (java.nio.ByteBuffer)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 ActiveMQBuffer (org.apache.activemq.artemis.api.core.ActiveMQBuffer)3 TimedBufferObserver (org.apache.activemq.artemis.core.io.buffer.TimedBufferObserver)3 IOCallback (org.apache.activemq.artemis.core.io.IOCallback)1 ReusableLatch (org.apache.activemq.artemis.utils.ReusableLatch)1