public void close() { if (m_in != null) { m_in.close(); // Interrupt the thread in case it's blocked on mailbox recv. m_inThread.interrupt(); try { m_inThread.join(); } catch (InterruptedException e) { } } if (m_ack != null) { m_ack.close(); try { m_ackThread.join(); } catch (InterruptedException e) { } } m_in = null; m_ack = null; }
/** * Process a message pulled off from the network thread, and discard the container once it's * processed. * * @param msg A pair of <sourceHSId, blockContainer> * @return The restore work, or null if there's no data block to return to the site. */ private RestoreWork processMessage( Pair<Long, Pair<Long, BBContainer>> msg, CachedByteBufferAllocator resultBufferAllocator) { if (msg == null) { return null; } RestoreWork restoreWork = null; long hsId = msg.getFirst(); long targetId = msg.getSecond().getFirst(); BBContainer container = msg.getSecond().getSecond(); try { ByteBuffer block = container.b(); byte typeByte = block.get(StreamSnapshotDataTarget.typeOffset); final int blockIndex = block.getInt(StreamSnapshotDataTarget.blockIndexOffset); StreamSnapshotMessageType type = StreamSnapshotMessageType.values()[typeByte]; if (type == StreamSnapshotMessageType.FAILURE) { VoltDB.crashLocalVoltDB("Rejoin source sent failure message.", false, null); // for test code only if (m_expectedEOFs.decrementAndGet() == 0) { m_EOF = true; } } else if (type == StreamSnapshotMessageType.END) { if (rejoinLog.isTraceEnabled()) { rejoinLog.trace("Got END message " + blockIndex); } // End of stream, no need to ack this buffer if (m_expectedEOFs.decrementAndGet() == 0) { m_EOF = true; } } else if (type == StreamSnapshotMessageType.SCHEMA) { rejoinLog.trace("Got SCHEMA message"); block.position(StreamSnapshotDataTarget.contentOffset); byte[] schemaBytes = new byte[block.remaining()]; block.get(schemaBytes); m_schemas.put(block.getInt(StreamSnapshotDataTarget.tableIdOffset), schemaBytes); } else if (type == StreamSnapshotMessageType.HASHINATOR) { block.position(StreamSnapshotDataTarget.contentOffset); long version = block.getLong(); byte[] hashinatorConfig = new byte[block.remaining()]; block.get(hashinatorConfig); restoreWork = new HashinatorRestoreWork(version, hashinatorConfig); } else { // It's normal snapshot data afterwards final int tableId = block.getInt(StreamSnapshotDataTarget.tableIdOffset); if (!m_schemas.containsKey(tableId)) { VoltDB.crashLocalVoltDB("No schema for table with ID " + tableId, false, null); } // Get the byte buffer ready to be consumed block.position(StreamSnapshotDataTarget.contentOffset); ByteBuffer nextChunk = getNextChunk(m_schemas.get(tableId), block, resultBufferAllocator); m_bytesReceived += nextChunk.remaining(); restoreWork = new TableRestoreWork(tableId, nextChunk); } // Queue ack to this block m_ack.ack(hsId, m_EOF, targetId, blockIndex); return restoreWork; } finally { container.discard(); } }