Package org.voltdb.rejoin

Source Code of org.voltdb.rejoin.StreamSnapshotDataReceiver

/* This file is part of VoltDB.
* Copyright (C) 2008-2014 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.voltdb.rejoin;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.voltcore.logging.VoltLogger;
import org.voltcore.messaging.Mailbox;
import org.voltcore.messaging.VoltMessage;
import org.voltcore.utils.DBBPool.BBContainer;
import org.voltcore.utils.Pair;
import org.voltdb.SnapshotSiteProcessor;
import org.voltdb.utils.CompressionService;
import org.voltdb.utils.FixedDBBPool;

/**
* Receives snapshot data from a replica. This is used on a rejoining partition.
*/
public class StreamSnapshotDataReceiver extends StreamSnapshotBase
implements Runnable {
    private static final VoltLogger rejoinLog = new VoltLogger("REJOIN");

    /*
     * element is a pair of <sourceHSId, blockData>. The hsId should remain the
     * same for the length of the data transfer process for this partition.
     */
    private final LinkedBlockingQueue<Pair<Long, Pair<Long, BBContainer>>> m_queue =
            new LinkedBlockingQueue<Pair<Long, Pair<Long, BBContainer>>>();

    private final Mailbox m_mb;
    private final FixedDBBPool m_bufferPool;
    private volatile boolean m_closed = false;

    public StreamSnapshotDataReceiver(Mailbox mb, FixedDBBPool bufferPool) {
        super();
        m_mb = mb;
        m_bufferPool = bufferPool;
    }

    public void close() {
        m_closed = true;
    }

    /**
     * Get the next message from queue.
     *
     * @return null if the queue is empty.
     */
    public Pair<Long, Pair<Long, BBContainer>> poll() {
        return m_queue.poll();
    }

    /**
     * Get the next message from the queue. This blocks until one is available.
     *
     * @return
     * @throws InterruptedException
     */
    public Pair<Long, Pair<Long, BBContainer>> take() throws InterruptedException {
        return m_queue.take();
    }

    public int size() {
        return m_queue.size();
    }

    @Override
    public void run() {
        BlockingQueue<BBContainer> bufferQueue =
            m_bufferPool.getQueue(SnapshotSiteProcessor.m_snapshotBufferLength);
        BlockingQueue<BBContainer> compressionBufferQueue =
            m_bufferPool.getQueue(SnapshotSiteProcessor.m_snapshotBufferCompressedLen);

        try {
            while (true) {
                BBContainer container = null;
                BBContainer compressionBufferC = null;
                ByteBuffer compressionBuffer = null;
                boolean success = false;

                try {
                    VoltMessage msg = m_mb.recvBlocking();
                    if (msg == null) {
                        // If interrupted, break
                        break;
                    }

                    assert(msg instanceof RejoinDataMessage);
                    RejoinDataMessage dataMsg = (RejoinDataMessage) msg;
                    byte[] data = dataMsg.getData();

                    // Only grab the buffer from the pool after receiving a message from the
                    // mailbox. If the buffer is grabbed before receiving the message,
                    // this thread could hold on to a buffer it may not need and other receivers
                    // will be blocked if the pool has no more buffers left.
                    container = bufferQueue.take();
                    ByteBuffer messageBuffer = container.b();
                    messageBuffer.clear();

                    compressionBufferC = compressionBufferQueue.take();
                    compressionBuffer = compressionBufferC.b();
                    compressionBuffer.clear();
                    compressionBuffer.limit(data.length);
                    compressionBuffer.put(data);
                    compressionBuffer.flip();
                    int uncompressedSize =
                            CompressionService.decompressBuffer(
                                    compressionBuffer,
                                    messageBuffer);
                    messageBuffer.limit(uncompressedSize);
                    m_queue.offer(Pair.of(dataMsg.m_sourceHSId, Pair.of(dataMsg.getTargetId(), container)));
                    success = true;
                } finally {
                    if (!success && container != null) {
                        container.discard();
                    }
                    if (compressionBuffer != null) {
                        compressionBufferC.discard();
                    }
                }
            }
        } catch (IOException e) {
            /*
             * Wait until the last message is delivered and then wait some more
             * so it can be processed so that closed can be set and the
             * exception suppressed.
             */
            try {
                while (!m_queue.isEmpty()) {
                    Thread.sleep(50);
                }
                Thread.sleep(300);
            } catch (InterruptedException e2) {}
            if (m_closed) {
                return;
            }
            rejoinLog.error("Error reading a message from a recovery stream.", e);
        } catch (InterruptedException e) {
            return;
        }
    }
}
TOP

Related Classes of org.voltdb.rejoin.StreamSnapshotDataReceiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.