All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fluxtion.agrona.concurrent.broadcast.CopyBroadcastReceiver Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014-2024 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fluxtion.agrona.concurrent.broadcast;

import com.fluxtion.agrona.MutableDirectBuffer;
import com.fluxtion.agrona.concurrent.MessageHandler;
import com.fluxtion.agrona.concurrent.UnsafeBuffer;

import java.nio.ByteBuffer;

/**
 * Receiver that copies messages which have been broadcast to enable a simpler API for the client.
 */
public class CopyBroadcastReceiver
{
    /**
     * Default length for the scratch buffer for copying messages into.
     */
    public static final int SCRATCH_BUFFER_LENGTH = 4096;

    private final BroadcastReceiver receiver;
    private final MutableDirectBuffer scratchBuffer;

    /**
     * Wrap a {@link BroadcastReceiver} to simplify the API for receiving messages.
     *
     * @param receiver      to be wrapped.
     * @param scratchBuffer to be used for copying receive buffers.
     */
    public CopyBroadcastReceiver(final BroadcastReceiver receiver, final MutableDirectBuffer scratchBuffer)
    {
        this.receiver = receiver;
        this.scratchBuffer = scratchBuffer;
    }

    /**
     * Get the underlying {@link BroadcastReceiver} which this is wrapping and copying out of.
     *
     * @return the underlying {@link BroadcastReceiver} which this is wrapping and copying out of.
     */
    public BroadcastReceiver broadcastReceiver()
    {
        return receiver;
    }

    /**
     * Wrap a {@link BroadcastReceiver} to simplify the API for receiving messages.
     *
     * @param receiver            to be wrapped.
     * @param scratchBufferLength is the maximum length of a message to be copied when receiving.
     */
    public CopyBroadcastReceiver(final BroadcastReceiver receiver, final int scratchBufferLength)
    {
        this.receiver = receiver;
        scratchBuffer = new UnsafeBuffer(ByteBuffer.allocateDirect(scratchBufferLength));
    }

    /**
     * Wrap a {@link BroadcastReceiver} to simplify the API for receiving messages.
     *
     * @param receiver to be wrapped.
     */
    public CopyBroadcastReceiver(final BroadcastReceiver receiver)
    {
        this(receiver, SCRATCH_BUFFER_LENGTH);
    }

    /**
     * Receive one message from the broadcast buffer.
     *
     * @param handler to be called for each message received.
     * @return the number of messages that have been received.
     */
    public int receive(final MessageHandler handler)
    {
        int messagesReceived = 0;
        final BroadcastReceiver receiver = this.receiver;
        final long lastSeenLappedCount = receiver.lappedCount();

        if (receiver.receiveNext())
        {
            if (lastSeenLappedCount != receiver.lappedCount())
            {
                throw new IllegalStateException("unable to keep up with broadcast");
            }

            final int length = receiver.length();
            final int capacity = scratchBuffer.capacity();
            if (length > capacity && !scratchBuffer.isExpandable())
            {
                throw new IllegalStateException(
                    "buffer required length of " + length + " but only has " + capacity);
            }

            final int msgTypeId = receiver.typeId();
            scratchBuffer.putBytes(0, receiver.buffer(), receiver.offset(), length);

            if (!receiver.validate())
            {
                throw new IllegalStateException("unable to keep up with broadcast");
            }

            handler.onMessage(msgTypeId, scratchBuffer, 0, length);

            messagesReceived = 1;
        }

        return messagesReceived;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy