Search in sources :

Example 1 with Frame

use of com.rabbitmq.client.impl.Frame in project rabbitmq-java-client by rabbitmq.

the class FrameBuilderTest method buildFramesInOneGo.

@Test
public void buildFramesInOneGo() throws IOException {
    byte[] frameContent = new byte[] { 1, 0, 0, 0, 0, 0, 3, 1, 2, 3, end() };
    int nbFrames = 13;
    byte[] frames = new byte[frameContent.length * nbFrames];
    for (int i = 0; i < nbFrames; i++) {
        for (int j = 0; j < frameContent.length; j++) {
            frames[i * frameContent.length + j] = frameContent[j];
        }
    }
    buffer = ByteBuffer.wrap(frames);
    builder = new FrameBuilder(channel, buffer);
    int frameCount = 0;
    Frame frame;
    while ((frame = builder.readFrame()) != null) {
        assertThat(frame).isNotNull();
        assertThat(frame.getType()).isEqualTo(1);
        assertThat(frame.getChannel()).isEqualTo(0);
        assertThat(frame.getPayload()).hasSize(3);
        frameCount++;
    }
    assertThat(frameCount).isEqualTo(nbFrames);
}
Also used : Frame(com.rabbitmq.client.impl.Frame) FrameBuilder(com.rabbitmq.client.impl.nio.FrameBuilder) Test(org.junit.Test)

Example 2 with Frame

use of com.rabbitmq.client.impl.Frame in project rabbitmq-java-client by rabbitmq.

the class FrameBuilderTest method buildFrameInOneGo.

@Test
public void buildFrameInOneGo() throws IOException {
    buffer = ByteBuffer.wrap(new byte[] { 1, 0, 0, 0, 0, 0, 3, 1, 2, 3, end() });
    builder = new FrameBuilder(channel, buffer);
    Frame frame = builder.readFrame();
    assertThat(frame).isNotNull();
    assertThat(frame.getType()).isEqualTo(1);
    assertThat(frame.getChannel()).isEqualTo(0);
    assertThat(frame.getPayload()).hasSize(3);
}
Also used : Frame(com.rabbitmq.client.impl.Frame) FrameBuilder(com.rabbitmq.client.impl.nio.FrameBuilder) Test(org.junit.Test)

Example 3 with Frame

use of com.rabbitmq.client.impl.Frame in project rabbitmq-java-client by rabbitmq.

the class NioLoop method run.

@Override
public void run() {
    final SelectorHolder selectorState = context.readSelectorState;
    final Selector selector = selectorState.selector;
    final Set<SocketChannelRegistration> registrations = selectorState.registrations;
    final ByteBuffer buffer = context.readBuffer;
    final SelectorHolder writeSelectorState = context.writeSelectorState;
    final Selector writeSelector = writeSelectorState.selector;
    final Set<SocketChannelRegistration> writeRegistrations = writeSelectorState.registrations;
    // whether there have been write registrations in the previous loop
    // registrations are done after Selector.select(), to work on clean keys
    // thus, any write operation is performed in the next loop
    // we don't want to wait in the read Selector.select() if there are
    // pending writes
    boolean writeRegistered = false;
    try {
        while (!Thread.currentThread().isInterrupted()) {
            for (SelectionKey selectionKey : selector.keys()) {
                SocketChannelFrameHandlerState state = (SocketChannelFrameHandlerState) selectionKey.attachment();
                if (state.getConnection() != null && state.getConnection().getHeartbeat() > 0) {
                    long now = System.currentTimeMillis();
                    if ((now - state.getLastActivity()) > state.getConnection().getHeartbeat() * 1000 * 2) {
                        try {
                            handleHeartbeatFailure(state);
                        } catch (Exception e) {
                            LOGGER.warn("Error after heartbeat failure of connection {}", state.getConnection());
                        } finally {
                            selectionKey.cancel();
                        }
                    }
                }
            }
            int select;
            if (!writeRegistered && registrations.isEmpty() && writeRegistrations.isEmpty()) {
                // we can block, registrations will call Selector.wakeup()
                select = selector.select(1000);
                if (selector.keys().size() == 0) {
                    // we haven't been doing anything for a while, shutdown state
                    boolean clean = context.cleanUp();
                    if (clean) {
                        // we stop this thread
                        return;
                    }
                // there may be incoming connections, keep going
                }
            } else {
                // we don't have to block, we need to select and clean cancelled keys before registration
                select = selector.selectNow();
            }
            writeRegistered = false;
            // registrations should be done after select,
            // once the cancelled keys have been actually removed
            SocketChannelRegistration registration;
            Iterator<SocketChannelRegistration> registrationIterator = registrations.iterator();
            while (registrationIterator.hasNext()) {
                registration = registrationIterator.next();
                registrationIterator.remove();
                int operations = registration.operations;
                try {
                    if (registration.state.getChannel().isOpen()) {
                        registration.state.getChannel().register(selector, operations, registration.state);
                    }
                } catch (Exception e) {
                    // can happen if the channel has been closed since the operation has been enqueued
                    LOGGER.info("Error while registering socket channel for read: {}", e.getMessage());
                }
            }
            if (select > 0) {
                Set<SelectionKey> readyKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = readyKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if (!key.isValid()) {
                        continue;
                    }
                    if (key.isReadable()) {
                        final SocketChannelFrameHandlerState state = (SocketChannelFrameHandlerState) key.attachment();
                        try {
                            if (!state.getChannel().isOpen()) {
                                key.cancel();
                                continue;
                            }
                            if (state.getConnection() == null) {
                                // let's wait a bit more
                                continue;
                            }
                            state.prepareForReadSequence();
                            while (state.continueReading()) {
                                final Frame frame = state.frameBuilder.readFrame();
                                if (frame != null) {
                                    try {
                                        boolean noProblem = state.getConnection().handleReadFrame(frame);
                                        if (noProblem && (!state.getConnection().isRunning() || state.getConnection().hasBrokerInitiatedShutdown())) {
                                            // looks like the frame was Close-Ok or Close
                                            dispatchShutdownToConnection(state);
                                            key.cancel();
                                            break;
                                        }
                                    } catch (Throwable ex) {
                                        // problem during frame processing, tell connection, and
                                        // we can stop for this channel
                                        handleIoError(state, ex);
                                        key.cancel();
                                        break;
                                    }
                                }
                            }
                            state.setLastActivity(System.currentTimeMillis());
                        } catch (final Exception e) {
                            LOGGER.warn("Error during reading frames", e);
                            handleIoError(state, e);
                            key.cancel();
                        } finally {
                            buffer.clear();
                        }
                    }
                }
            }
            // write loop
            select = writeSelector.selectNow();
            // registrations should be done after select,
            // once the cancelled keys have been actually removed
            SocketChannelRegistration writeRegistration;
            Iterator<SocketChannelRegistration> writeRegistrationIterator = writeRegistrations.iterator();
            while (writeRegistrationIterator.hasNext()) {
                writeRegistration = writeRegistrationIterator.next();
                writeRegistrationIterator.remove();
                int operations = writeRegistration.operations;
                try {
                    if (writeRegistration.state.getChannel().isOpen()) {
                        writeRegistration.state.getChannel().register(writeSelector, operations, writeRegistration.state);
                        writeRegistered = true;
                    }
                } catch (Exception e) {
                    // can happen if the channel has been closed since the operation has been enqueued
                    LOGGER.info("Error while registering socket channel for write: {}", e.getMessage());
                }
            }
            if (select > 0) {
                Set<SelectionKey> readyKeys = writeSelector.selectedKeys();
                Iterator<SelectionKey> iterator = readyKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    SocketChannelFrameHandlerState state = (SocketChannelFrameHandlerState) key.attachment();
                    if (!key.isValid()) {
                        continue;
                    }
                    if (key.isWritable()) {
                        boolean cancelKey = true;
                        try {
                            if (!state.getChannel().isOpen()) {
                                key.cancel();
                                continue;
                            }
                            state.prepareForWriteSequence();
                            int toBeWritten = state.getWriteQueue().size();
                            int written = 0;
                            DataOutputStream outputStream = state.outputStream;
                            WriteRequest request;
                            while (written <= toBeWritten && (request = state.getWriteQueue().poll()) != null) {
                                request.handle(outputStream);
                                written++;
                            }
                            outputStream.flush();
                            if (!state.getWriteQueue().isEmpty()) {
                                cancelKey = true;
                            }
                        } catch (Exception e) {
                            handleIoError(state, e);
                        } finally {
                            state.endWriteSequence();
                            if (cancelKey) {
                                key.cancel();
                            }
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        LOGGER.error("Error in NIO loop", e);
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) Frame(com.rabbitmq.client.impl.Frame) DataOutputStream(java.io.DataOutputStream) ByteBuffer(java.nio.ByteBuffer) IOException(java.io.IOException) Selector(java.nio.channels.Selector)

Example 4 with Frame

use of com.rabbitmq.client.impl.Frame in project rabbitmq-java-client by rabbitmq.

the class FrameTest method writeFrames.

@Test
public void writeFrames() throws IOException {
    List<Frame> frames = new ArrayList<Frame>();
    Random random = new Random();
    int totalFrameSize = 0;
    for (int i = 0; i < 100; i++) {
        byte[] payload = new byte[random.nextInt(2000) + 1];
        Frame frame = new Frame(AMQP.FRAME_METHOD, 1, payload);
        frames.add(frame);
        totalFrameSize += frame.size();
    }
    AccumulatorWritableByteChannel channel = new AccumulatorWritableByteChannel();
    ByteBuffer buffer = ByteBuffer.allocate(8192);
    for (Frame frame : frames) {
        frame.writeTo(new DataOutputStream(new ByteBufferOutputStream(channel, buffer)));
    }
    drain(channel, buffer);
    checkWrittenChunks(totalFrameSize, channel);
}
Also used : Frame(com.rabbitmq.client.impl.Frame) Random(java.util.Random) ByteBufferOutputStream(com.rabbitmq.client.impl.nio.ByteBufferOutputStream) DataOutputStream(java.io.DataOutputStream) ArrayList(java.util.ArrayList) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 5 with Frame

use of com.rabbitmq.client.impl.Frame in project rabbitmq-java-client by rabbitmq.

the class FrameTest method writeLargeFrame.

@Test
public void writeLargeFrame() throws IOException {
    List<Frame> frames = new ArrayList<Frame>();
    int totalFrameSize = 0;
    int[] framesSize = new int[] { 100, 75, 20000, 150 };
    for (int frameSize : framesSize) {
        Frame frame = new Frame(AMQP.FRAME_METHOD, 1, new byte[frameSize]);
        frames.add(frame);
        totalFrameSize += frame.size();
    }
    AccumulatorWritableByteChannel channel = new AccumulatorWritableByteChannel();
    ByteBuffer buffer = ByteBuffer.allocate(8192);
    for (Frame frame : frames) {
        frame.writeTo(new DataOutputStream(new ByteBufferOutputStream(channel, buffer)));
    }
    drain(channel, buffer);
    checkWrittenChunks(totalFrameSize, channel);
}
Also used : Frame(com.rabbitmq.client.impl.Frame) ByteBufferOutputStream(com.rabbitmq.client.impl.nio.ByteBufferOutputStream) DataOutputStream(java.io.DataOutputStream) ArrayList(java.util.ArrayList) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Aggregations

Frame (com.rabbitmq.client.impl.Frame)9 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)4 FrameBuilder (com.rabbitmq.client.impl.nio.FrameBuilder)3 DataOutputStream (java.io.DataOutputStream)3 IOException (java.io.IOException)3 ByteBuffer (java.nio.ByteBuffer)3 UnexpectedFrameError (com.rabbitmq.client.UnexpectedFrameError)2 AMQConnection (com.rabbitmq.client.impl.AMQConnection)2 ByteBufferOutputStream (com.rabbitmq.client.impl.nio.ByteBufferOutputStream)2 AMQP (com.rabbitmq.client.AMQP)1 AMQBasicProperties (com.rabbitmq.client.impl.AMQBasicProperties)1 Publish (com.rabbitmq.client.impl.AMQImpl.Basic.Publish)1 SelectionKey (java.nio.channels.SelectionKey)1 Selector (java.nio.channels.Selector)1 HashMap (java.util.HashMap)1 Random (java.util.Random)1