コード例 #1
0
        public void Handle(ReplicationMessage.RawChunkBulk message)
        {
            if (_subscriptionId != message.SubscriptionId)
            {
                return;
            }
            if (_activeChunk == null)
            {
                ReplicationFail(
                    "Physical chunk bulk received, but we do not have active chunk.",
                    "Physical chunk bulk received, but we do not have active chunk.");
            }

            if (_activeChunk.ChunkHeader.ChunkStartNumber != message.ChunkStartNumber ||
                _activeChunk.ChunkHeader.ChunkEndNumber != message.ChunkEndNumber)
            {
                Log.Error(
                    "Received RawChunkBulk for TFChunk {chunkStartNumber}-{chunkEndNumber}, but active chunk is {activeChunk}.",
                    message.ChunkStartNumber, message.ChunkEndNumber, _activeChunk);
                return;
            }

            if (_activeChunk.RawWriterPosition != message.RawPosition)
            {
                Log.Error(
                    "Received RawChunkBulk at raw pos {rawPosition} (0x{rawPosition:X}) while current writer raw pos is {rawWriterPosition} (0x{rawWriterPosition:X}).",
                    message.RawPosition, message.RawPosition, _activeChunk.RawWriterPosition,
                    _activeChunk.RawWriterPosition);
                return;
            }

            if (!_activeChunk.TryAppendRawData(message.RawBytes))
            {
                ReplicationFail(
                    "Could not append raw bytes to chunk {0}-{1}, raw pos: {2} (0x{3:X}), bytes length: {4} (0x{5:X}). Chunk file size: {6} (0x{7:X}).",
                    "Could not append raw bytes to chunk {chunkStartNumber}-{chunkEndNumber}, raw pos: {rawPosition} (0x{rawPosition:X}), bytes length: {rawBytesLength} (0x{rawBytesLength:X}). Chunk file size: {chunkFileSize} (0x{chunkFileSize:X}).",
                    message.ChunkStartNumber, message.ChunkEndNumber, message.RawPosition, message.RawPosition,
                    message.RawBytes.Length, message.RawBytes.Length, _activeChunk.FileSize, _activeChunk.FileSize);
            }

            _subscriptionPos += message.RawBytes.Length;

            if (message.CompleteChunk)
            {
                Log.Trace("Completing raw chunk {chunkStartNumber}-{chunkEndNumber}...", message.ChunkStartNumber,
                          message.ChunkEndNumber);
                Writer.CompleteReplicatedRawChunk(_activeChunk);

                _subscriptionPos = _activeChunk.ChunkHeader.ChunkEndPosition;
                _framer.Reset();
                _activeChunk = null;
            }

            if (message.CompleteChunk ||
                _subscriptionPos - _ackedSubscriptionPos >= MasterReplicationService.ReplicaAckWindow)
            {
                _ackedSubscriptionPos = _subscriptionPos;
                Bus.Publish(new ReplicationMessage.AckLogPosition(_subscriptionId, _ackedSubscriptionPos));
            }
        }
コード例 #2
0
        private TcpPackage WrapRawChunkBulk(ReplicationMessage.RawChunkBulk msg)
        {
            var dto = new ReplicationMessageDto.RawChunkBulk(msg.LeaderId.ToByteArray(),
                                                             msg.SubscriptionId.ToByteArray(),
                                                             msg.ChunkStartNumber,
                                                             msg.ChunkEndNumber,
                                                             msg.RawPosition,
                                                             msg.RawBytes,
                                                             msg.CompleteChunk);

            return(new TcpPackage(TcpCommand.RawChunkBulk, Guid.NewGuid(), dto.Serialize()));
        }
コード例 #3
0
        private bool TrySendLogBulk(ReplicaSubscription subscription, long masterCheckpoint)
        {
            /*
             * if (subscription == null) throw new Exception("subscription == null");
             * if (subscription.BulkReader == null) throw new Exception("subscription.BulkReader == null");
             * if (subscription.BulkReader.Chunk == null) throw new Exception("subscription.BulkReader.Chunk == null");
             * if (subscription.DataBuffer == null) throw new Exception("subscription.DataBuffer == null");
             */

            var bulkReader  = subscription.BulkReader;
            var chunkHeader = bulkReader.Chunk.ChunkHeader;

            BulkReadResult bulkResult;

            if (subscription.RawSend)
            {
                bulkResult = bulkReader.ReadNextRawBytes(subscription.DataBuffer.Length, subscription.DataBuffer);
            }
            else
            {
                var bytesToRead = (int)Math.Min(subscription.DataBuffer.Length, masterCheckpoint - subscription.LogPosition);
                bulkResult = bulkReader.ReadNextDataBytes(bytesToRead, subscription.DataBuffer);
            }

            bool dataFound = false;

            // for logical send we can get 0 at the end multiple time, but we need to get EOF exactly once
            if (bulkResult.BytesRead > 0 || (bulkResult.IsEOF && !subscription.RawSend && !subscription.EOFSent))
            {
                var data = new byte[bulkResult.BytesRead];
                Buffer.BlockCopy(subscription.DataBuffer, 0, data, 0, bulkResult.BytesRead);

                dataFound            = true;
                subscription.EOFSent = bulkResult.IsEOF;

                if (subscription.RawSend)
                {
                    var msg = new ReplicationMessage.RawChunkBulk(
                        _instanceId, subscription.SubscriptionId, chunkHeader.ChunkStartNumber, chunkHeader.ChunkEndNumber,
                        bulkResult.OldPosition, data, bulkResult.IsEOF);
                    subscription.SendMessage(msg);
                }
                else
                {
                    if (chunkHeader.GetLocalLogPosition(subscription.LogPosition) != bulkResult.OldPosition)
                    {
                        throw new Exception(string.Format("Replication invariant failure. SubscriptionPosition {0}, bulkResult.OldPosition {1}",
                                                          subscription.LogPosition, bulkResult.OldPosition));
                    }
                    var msg = new ReplicationMessage.DataChunkBulk(
                        _instanceId, subscription.SubscriptionId, chunkHeader.ChunkStartNumber, chunkHeader.ChunkEndNumber,
                        subscription.LogPosition, data, bulkResult.IsEOF);
                    subscription.LogPosition += bulkResult.BytesRead;
                    subscription.SendMessage(msg);
                }
            }

            if (bulkResult.IsEOF)
            {
                var newLogPosition = chunkHeader.ChunkEndPosition;
                if (newLogPosition < masterCheckpoint)
                {
                    dataFound = true;
                    SetSubscriptionPosition(subscription, newLogPosition, Guid.Empty, replicationStart: false, verbose: true, trial: 0);
                }
            }
            return(dataFound);
        }