/* This file is part of VoltDB. * Copyright (C) 2008-2017 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.util.concurrent.LinkedBlockingQueue; import org.voltcore.logging.VoltLogger; import org.voltcore.messaging.Mailbox; import org.voltcore.utils.Pair; /** * Sends acks of snapshot blocks to the snapshot sender. */ public class StreamSnapshotAckSender implements Runnable { private static final VoltLogger rejoinLog = new VoltLogger("REJOIN"); private final Mailbox m_mb; private final LinkedBlockingQueue<Pair<Long, RejoinDataAckMessage>> m_blockIndices = new LinkedBlockingQueue<Pair<Long, RejoinDataAckMessage>>(); public StreamSnapshotAckSender(Mailbox mb) { m_mb = mb; } public void close() { // null message terminates the thread m_blockIndices.offer(Pair.of(-1L, (RejoinDataAckMessage) null)); } /** * Ack with a positive block index. * @param hsId The mailbox to send the ack to * @param blockIndex */ public void ack(long hsId, boolean isEOS, long targetId, int blockIndex) { m_blockIndices.offer(Pair.of(hsId, new RejoinDataAckMessage(isEOS, targetId, blockIndex))); } @Override public void run() { while (true) { long hsId; RejoinDataAckMessage ackMsg; try { Pair<Long, RejoinDataAckMessage> work = m_blockIndices.take(); hsId = work.getFirst(); ackMsg = work.getSecond(); } catch (InterruptedException e1) { break; } if (ackMsg == null) { rejoinLog.debug(m_blockIndices.size() + " acks remaining, " + "terminating ack sender"); // special value of -1 terminates the thread break; } m_mb.send(hsId, ackMsg); } } }