示例#1
0
 internal LoggingReplicatorCopyStream(
     ReplicatedLogManager replicatedLogManager,
     IStateManager stateManager,
     CheckpointManager checkpointManager,
     Func <LogicalSequenceNumber, Task> waitForLogFlushUptoLsn,
     long replicaId,
     LogicalSequenceNumber uptoLsn,
     IOperationDataStream copyContext,
     ITracer tracer)
 {
     this.stateManager           = stateManager;
     this.checkpointManager      = checkpointManager;
     this.replicatedLogManager   = replicatedLogManager;
     this.replicaId              = replicaId;
     this.waitForLogFlushUptoLsn = waitForLogFlushUptoLsn;
     this.uptoLsn               = uptoLsn;
     this.copyContext           = copyContext;
     this.targetReplicaId       = 0;
     this.targetProgressVector  = null;
     this.targetLogHeadEpoch    = LogicalSequenceNumber.InvalidEpoch;
     this.targetLogHeadLsn      = LogicalSequenceNumber.InvalidLsn;
     this.currentTargetLsn      = LogicalSequenceNumber.InvalidLsn;
     this.copyStage             = CopyStage.CopyMetadata;
     this.copyStateStream       = null;
     this.copiedRecordNumber    = 0;
     this.sourceStartingLsn     = LogicalSequenceNumber.InvalidLsn;
     this.targetStartingLsn     = LogicalSequenceNumber.InvalidLsn;
     this.logRecordsToCopy      = null;
     this.beginCheckpointRecord = null;
     this.bw         = new BinaryWriter(new MemoryStream());
     this.isDisposed = false;
     this.tracer     = tracer;
 }
示例#2
0
        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    // Trace that copy has completed if we started.
                    FabricEvents.Events.CopyAsync(this.traceType, "disposing");

                    if (this.currentFileStream != null)
                    {
                        this.currentFileStream.Dispose();
                        this.currentFileStream = null;
                    }

                    if (this.copySnapshotOfMetadataTableEnumerator != null)
                    {
                        this.copySnapshotOfMetadataTableEnumerator.Dispose();
                        this.copySnapshotOfMetadataTableEnumerator = null;
                    }

                    if (this.copySnapshotOfMetadataTable != null)
                    {
                        this.copySnapshotOfMetadataTable.ReleaseRef();
                        this.copySnapshotOfMetadataTable = null;
                    }
                }

                this.copyStage = CopyStage.None;
            }

            this.disposed = true;
        }
示例#3
0
        internal static void Assert(bool condition, string format, CopyStage param1)
        {
            if (condition == false)
            {
                var failFastMessage = string.Format(System.Globalization.CultureInfo.InvariantCulture, format, param1);
                FailFast(failFastMessage);

                // AMW - Force break into debugger for ease of debugging
                Debugger.Break();
            }
        }
示例#4
0
        private OperationData GetCopyMetadata(CopyStage copyStageToWrite)
        {
            OperationData result;

            using (var stream = new MemoryStream(CopyMetadataByteSize))
            {
                using (var bw = new BinaryWriter(stream))
                {
                    // First 4 bytes are reserved for the version of the metadata.
                    bw.Write(CopyMetadataVersion);

                    bw.Write((int)copyStageToWrite);
                    bw.Write(this.replicaId);

                    result = new OperationData(new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Position));
                }
            }

            var trace = "Copying Metadata. CopyStage: " + this.copyStage + " SourceStartingLSN: "
                        + this.sourceStartingLsn.LSN + " TargetStartingLSN: " + this.targetStartingLsn.LSN;

            FabricEvents.Events.CopyStreamGetNext(tracer.Type, trace);
            return(result);
        }
示例#5
0
        private async Task <OperationData> GetNextAsyncSafe(CancellationToken cancellationToken)
        {
            OperationData data;

            if (this.copyStage == CopyStage.CopyMetadata)
            {
                data = await this.copyContext.GetNextAsync(CancellationToken.None).ConfigureAwait(false);

                Utility.Assert(data.Count == 1, "data.Count == 1");

                var bytes = data[0].Array;

                using (var br = new BinaryReader(new MemoryStream(bytes, data[0].Offset, data[0].Count)))
                {
                    this.targetReplicaId      = br.ReadInt64();
                    this.targetProgressVector = new ProgressVector();
                    this.targetProgressVector.Read(br, false);
                    var targetLogHeadDatalossNumber      = br.ReadInt64();
                    var targetLogHeadConfigurationNumber = br.ReadInt64();
                    this.targetLogHeadEpoch = new Epoch(targetLogHeadDatalossNumber, targetLogHeadConfigurationNumber);
                    this.targetLogHeadLsn   = new LogicalSequenceNumber(br.ReadInt64());
                    this.currentTargetLsn   = new LogicalSequenceNumber(br.ReadInt64());
                    this.latestRecoveredAtomicRedoOperationLsn = br.ReadInt64();
                }

                var message =
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Target Replica Copy Context: {0}" + Environment.NewLine
                        + "     TargetLogHeadEpoch: {1},{2} TargetLogHeadLsn: {3} TargetLogTailEpoch: {4},{5} TargetLogTailLSN: {6}"
                        + Environment.NewLine
                        + "     SourceLogHeadEpoch: {7},{8} SourceLogHeadLsn: {9} SourceLogTailEpoch: {10},{11} SourceLogTailLSN: {12}"
                        + Environment.NewLine + "     Target ProgressVector: {13}" + Environment.NewLine
                        + "     Source ProgressVector: {14}" + Environment.NewLine
                        + "     LastRecoveredAtomicRedoOperationLsn: {15}",
                        this.targetReplicaId,
                        this.targetLogHeadEpoch.DataLossNumber,
                        this.targetLogHeadEpoch.ConfigurationNumber,
                        this.targetLogHeadLsn.LSN,
                        this.targetProgressVector.LastProgressVectorEntry.Epoch.DataLossNumber,
                        this.targetProgressVector.LastProgressVectorEntry.Epoch.ConfigurationNumber,
                        this.currentTargetLsn.LSN,
                        this.replicatedLogManager.CurrentLogHeadRecord.CurrentEpoch.DataLossNumber,
                        this.replicatedLogManager.CurrentLogHeadRecord.CurrentEpoch.ConfigurationNumber,
                        this.replicatedLogManager.CurrentLogHeadRecord.Lsn.LSN,
                        this.replicatedLogManager.CurrentLogTailEpoch.DataLossNumber,
                        this.replicatedLogManager.CurrentLogTailEpoch.ConfigurationNumber,
                        this.replicatedLogManager.CurrentLogTailLsn.LSN,
                        this.targetProgressVector.ToString(Constants.ProgressVectorMaxStringSizeInKb / 2),
                        this.replicatedLogManager.ProgressVector.ToString(Constants.ProgressVectorMaxStringSizeInKb / 2),
                        this.latestRecoveredAtomicRedoOperationLsn);

                FabricEvents.Events.CopyStreamMetadata(tracer.Type, message);

                await this.waitForLogFlushUptoLsn(this.uptoLsn).ConfigureAwait(false);

                CopyMode copyMode;
                await this.checkpointManager.AcquireBackupAndCopyConsistencyLockAsync("Copy").ConfigureAwait(false);

                try
                {
                    copyMode = this.checkpointManager.GetLogRecordsToCopy(
                        this.targetProgressVector,
                        this.targetLogHeadEpoch,
                        this.targetLogHeadLsn,
                        this.currentTargetLsn,
                        this.latestRecoveredAtomicRedoOperationLsn,
                        this.targetReplicaId,
                        out this.sourceStartingLsn,
                        out this.targetStartingLsn,
                        out this.logRecordsToCopy,
                        out this.beginCheckpointRecord);
                }
                finally
                {
                    this.checkpointManager.ReleaseBackupAndCopyConsistencyLock("Copy");
                }

                CopyStage copyStageToWrite;
                if (copyMode == CopyMode.None)
                {
                    this.copyStage   = CopyStage.CopyNone;
                    copyStageToWrite = CopyStage.CopyNone;
                }
                else if (copyMode == CopyMode.Full)
                {
                    this.copyStage       = CopyStage.CopyState;
                    copyStageToWrite     = CopyStage.CopyState;
                    this.copyStateStream = this.stateManager.GetCurrentState();
                }
                else if ((copyMode & CopyMode.FalseProgress) != 0)
                {
                    Utility.Assert(
                        this.sourceStartingLsn <= this.targetStartingLsn,
                        "this.sourceStartingLsn ({0}) <= this.targetStartingLsn ({1})",
                        this.sourceStartingLsn, this.targetStartingLsn);

                    this.copyStage   = CopyStage.CopyFalseProgress;
                    copyStageToWrite = CopyStage.CopyFalseProgress;
                }
                else
                {
                    this.copyStage   = CopyStage.CopyScanToStartingLsn;
                    copyStageToWrite = CopyStage.CopyLog;
                }

                return(this.GetCopyMetadata(copyStageToWrite));
            }

            if (this.copyStage == CopyStage.CopyState)
            {
                data = await this.copyStateStream.GetNextAsync(cancellationToken).ConfigureAwait(false);

                if (data != null)
                {
                    data.Add(CopyStateOperation);

                    FabricEvents.Events.CopyStreamGetNextNoise(
                        tracer.Type,
                        "Copying State Operation: " + this.copiedRecordNumber);

                    ++this.copiedRecordNumber;
                    return(data);
                }

                var disposableCopyStateStream = this.copyStateStream as IDisposable;
                if (disposableCopyStateStream != null)
                {
                    disposableCopyStateStream.Dispose();
                }

                if (this.uptoLsn < beginCheckpointRecord.LastStableLsn)
                {
                    // Ensure we copy records up to the stable LSN of the begin checkpoint record as part of the copy stream
                    // so that the idle can initiate a checkpoint and apply it as part of the copy pump itself

                    // Not doing the above will mean that the idle can get promoted to active even before the checkpoint is completed
                    // uptolsn is inclusive LSN
                    // BUG: RDBug #9269022:Replicator must rename copy log before changing role to active secondary during full builds
                    this.uptoLsn = beginCheckpointRecord.LastStableLsn;

                    var trace = "FullCopy: Copying Logs from " + this.sourceStartingLsn.LSN
                                + " to BC.LastStableLsn: " + beginCheckpointRecord.LastStableLsn.LSN + " as the upto lsn: " + this.uptoLsn + " was smaller than the checkpoint stable lsn";

                    FabricEvents.Events.CopyStreamGetNext(tracer.Type, trace);
                }

                data = this.GetCopyStateMetadata();

                this.copyStage          = CopyStage.CopyLog;
                this.copiedRecordNumber = 0;

                return(data);
            }

            if (this.copyStage == CopyStage.CopyFalseProgress)
            {
                this.copyStage = CopyStage.CopyScanToStartingLsn;

                this.bw.BaseStream.Position = 0;
                this.bw.Write(this.sourceStartingLsn.LSN);
                var stream = this.bw.BaseStream as MemoryStream;
                data = new OperationData(new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Position));
                data.Add(CopyFalseProgressOperation);

                var trace = "Copying False Progress. SourceStartingLSN: " + this.sourceStartingLsn.LSN
                            + " TargetStartingLSN: " + this.targetStartingLsn.LSN;

                FabricEvents.Events.CopyStreamGetNext(tracer.Type, trace);
                return(data);
            }

            LogRecord record;

            if (this.copyStage == CopyStage.CopyScanToStartingLsn)
            {
                var startingLsn = (this.sourceStartingLsn < this.targetStartingLsn)
                    ? this.sourceStartingLsn
                    : this.targetStartingLsn;

                do
                {
                    var hasMoved = await this.logRecordsToCopy.MoveNextAsync(cancellationToken).ConfigureAwait(false);

                    if (hasMoved == false)
                    {
                        goto Finish;
                    }

                    record = this.logRecordsToCopy.Current;
                    Utility.Assert(record.Lsn <= startingLsn, "record.Lsn <= startingLsn");
                } while (record.Lsn < startingLsn);

                // The log stream is positioned at the end of startingLsn at this point. The enumerator Current is pointing to the "startingLsn"
                this.copyStage = CopyStage.CopyLog;
            }

            if (this.copyStage == CopyStage.CopyLog)
            {
                do
                {
                    // This will start copying after the startingLsn record as expected
                    var hasMoved = await this.logRecordsToCopy.MoveNextAsync(cancellationToken).ConfigureAwait(false);

                    if (hasMoved == false)
                    {
                        goto Finish;
                    }

                    record = this.logRecordsToCopy.Current;
                } while (record is PhysicalLogRecord);

                if (record.Lsn > this.uptoLsn)
                {
                    goto Finish;
                }

                var logicalLogRecord = record as LogicalLogRecord;

                Utility.Assert(logicalLogRecord != null, "Must be a logical log record");

                data = logicalLogRecord.ToOperationData(this.bw);
                data.Add(CopyLogOperation);

                var trace = "Copying log record. LogRecordNumber: " + this.copiedRecordNumber + "Record Type: "
                            + record.RecordType + " LSN: " + record.Lsn.LSN;

                FabricEvents.Events.CopyStreamGetNextNoise(tracer.Type, trace);
                ++this.copiedRecordNumber;
                return(data);
            }

Finish:
            if (this.logRecordsToCopy != null)
            {
                this.logRecordsToCopy.Dispose();
            }

            FabricEvents.Events.CopyStreamFinished(tracer.Type, this.copiedRecordNumber);

            return(null);
        }
示例#6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CopyHeader"/> class.
 /// </summary>
 /// <param name="version">
 /// The version.
 /// </param>
 /// <param name="copyStage">
 /// The copy stage.
 /// </param>
 /// <param name="primaryReplicaId">
 /// The primary replica id.
 /// </param>
 public CopyHeader(int version, CopyStage copyStage, long primaryReplicaId)
 {
     this.version          = version;
     this.copyStage        = copyStage;
     this.primaryReplicaId = primaryReplicaId;
 }
示例#7
0
        /// <summary>
        /// Copy operations are returned.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <OperationData> GetNextAsync(CancellationToken cancellationToken)
        {
            var directory = this.copyProvider.WorkingDirectory;

            // Take a snapshot of the metadata table on first Copy operation.
            if (this.copySnapshotOfMetadataTable == null)
            {
                this.copySnapshotOfMetadataTable = await this.copyProvider.GetMetadataTableAsync().ConfigureAwait(false);

                Diagnostics.Assert(
                    this.copySnapshotOfMetadataTable != null,
                    this.traceType,
                    "IStoreCopyProvider.GetMetadataTableAsync() returned a null metadata table.");

                this.copySnapshotOfMetadataTableEnumerator = this.copySnapshotOfMetadataTable.Table.GetEnumerator();
            }

            // Send the copy protocol version first.
            if (this.copyStage == CopyStage.Version)
            {
                FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "starting. directory:{0}", directory));

                // Next copy stage.
                this.copyStage = CopyStage.MetadataTable;

                using (var memoryStream = new MemoryStream(sizeof(int) + sizeof(byte)))
                    using (var writer = new BinaryWriter(memoryStream))
                    {
                        // Write the copy protocol version number.
                        writer.Write(CopyManager.CopyProtocolVersion);

                        // Write a byte indicating the operation type is the copy protocol version.
                        writer.Write((byte)TStoreCopyOperation.Version);

                        // Send the version operation data.
                        FabricEvents.Events.CopyAsync(
                            this.traceType,
                            string.Format(System.Globalization.CultureInfo.InvariantCulture, "Version. version:{0} bytes:{1}", CopyManager.CopyProtocolVersion, memoryStream.Position));
                        return(new OperationData(new ArraySegment <byte>(memoryStream.GetBuffer(), 0, checked ((int)memoryStream.Position))));
                    }
            }

            // Send the metadata table next.
            if (this.copyStage == CopyStage.MetadataTable)
            {
                // Consistency checks.
                Diagnostics.Assert(this.copySnapshotOfMetadataTable != null, this.traceType, "Unexpected copy error. Master table to be copied is null.");

                // Next copy stage.
                if (this.copySnapshotOfMetadataTableEnumerator.MoveNext())
                {
                    this.copyStage = CopyStage.KeyFile;
                }
                else
                {
                    this.copyStage = CopyStage.Complete;
                }

                using (var memoryStream = new MemoryStream())
                {
                    // Write the full metadata table (this will typically be small - even with 1000 tracked files, this will be under 64 KB).
                    await MetadataManager.WriteAsync(this.copySnapshotOfMetadataTable, memoryStream).ConfigureAwait(false);

                    using (var writer = new BinaryWriter(memoryStream))
                    {
                        // Write a byte indicating the operation type is the full metadata table.
                        writer.Write((byte)TStoreCopyOperation.MetadataTable);

                        // Send the metadata table operation data.
                        FabricEvents.Events.CopyAsync(
                            this.traceType,
                            string.Format(System.Globalization.CultureInfo.InvariantCulture, "Metadata table. directory:{0} bytes:{1} Total number of checkpoint files:{2}", directory, memoryStream.Position, this.copySnapshotOfMetadataTable.Table.Count));
                        return(new OperationData(new ArraySegment <byte>(memoryStream.GetBuffer(), 0, checked ((int)memoryStream.Position))));
                    }
                }
            }

            // Send the key file.
            if (this.copyStage == CopyStage.KeyFile)
            {
                var bytesRead = 0;

                var shortFileName     = this.copySnapshotOfMetadataTableEnumerator.Current.Value.FileName;
                var dataFileName      = Path.Combine(directory, shortFileName);
                var keyCheckpointFile = dataFileName + KeyCheckpointFile.FileExtension;

                // If we don't have the current file stream opened, this is the first table chunk.
                if (this.currentFileStream == null)
                {
                    Diagnostics.Assert(
                        FabricFile.Exists(keyCheckpointFile),
                        this.traceType,
                        "Unexpected copy error. Expected file does not exist: {0}",
                        keyCheckpointFile);

                    // Open the file with asynchronous flag and 4096 cache size (C# default).
                    FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "Opening key file. file:{0}", shortFileName));

                    // MCoskun: Default IoPriorityHint is used.
                    // Reason: We do not know whether this copy might be used to build a replica that is or will be required for write quorum.
                    this.currentFileStream = FabricFile.Open(keyCheckpointFile, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous);

                    // Send the start of file operation data.
                    this.perfCounterWriter.StartMeasurement();
                    bytesRead = await this.currentFileStream.ReadAsync(this.copyDataBuffer, 0, CopyChunkSize, cancellationToken).ConfigureAwait(false);

                    this.perfCounterWriter.StopMeasurement(bytesRead);

                    using (var stream = new MemoryStream(this.copyDataBuffer, writable: true))
                        using (var writer = new BinaryWriter(stream))
                        {
                            stream.Position = bytesRead;
                            writer.Write((int)this.copySnapshotOfMetadataTableEnumerator.Current.Value.FileId);
                        }

                    this.copyDataBuffer[bytesRead + sizeof(int)] = (byte)TStoreCopyOperation.StartKeyFile;
                    FabricEvents.Events.CopyAsync(
                        this.traceType,
                        string.Format(System.Globalization.CultureInfo.InvariantCulture, "StartKeyFile. file:{0} bytes:{1} totalFileSize:{2}", shortFileName, bytesRead + sizeof(int) + 1, this.currentFileStream.Length));
                    return(new OperationData(new ArraySegment <byte>(this.copyDataBuffer, 0, bytesRead + sizeof(int) + 1)));
                }

                // The start of the current file has been sent.  Check if there are more chunks to be sent (if the stream is at the end, this will return zero).
                this.perfCounterWriter.StartMeasurement();
                bytesRead = await this.currentFileStream.ReadAsync(this.copyDataBuffer, 0, CopyChunkSize, cancellationToken).ConfigureAwait(false);

                this.perfCounterWriter.StopMeasurement(bytesRead);
                if (bytesRead > 0)
                {
                    // Send the partial table file operation data.
                    this.copyDataBuffer[bytesRead] = (byte)TStoreCopyOperation.WriteKeyFile;
                    FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "WriteKeyFile. level:{0} bytes:{1} Position:{2}", shortFileName, bytesRead + 1, this.currentFileStream.Position));
                    return(new OperationData(new ArraySegment <byte>(this.copyDataBuffer, 0, bytesRead + 1)));
                }

                // There is no more data in the current file.  Send the end of file marker, and prepare for the next copy stage.
                this.currentFileStream.Dispose();
                this.currentFileStream = null;

                // Now move to the value file.
                this.copyStage = CopyStage.ValueFile;

                // Send the end of file operation data.
                var endFileData = new ArraySegment <byte>(new[] { (byte)TStoreCopyOperation.EndKeyFile });
                FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "EndKeyFile. file:{0}", shortFileName));
                return(new OperationData(endFileData));
            }

            if (this.copyStage == CopyStage.ValueFile)
            {
                var bytesRead = 0;

                var shortFileName       = this.copySnapshotOfMetadataTableEnumerator.Current.Value.FileName;
                var dataFileName        = Path.Combine(directory, shortFileName);
                var valueCheckpointFile = dataFileName + ValueCheckpointFile.FileExtension;

                // If we don't have the current file opened, this is the first table chunk.
                if (this.currentFileStream == null)
                {
                    Diagnostics.Assert(
                        FabricFile.Exists(valueCheckpointFile),
                        this.traceType,
                        "Unexpected copy error. Expected file does not exist: {0}",
                        valueCheckpointFile);

                    // Open the file with asynchronous flag and 4096 cache size (C# default).
                    FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "Opening value file. directory:{0} file:{1}", directory, shortFileName));

                    // MCoskun: Default IoPriorityHint is used.
                    // Reason: We do not know whether this copy might be used to build a replica that is or will be required for write quorum.
                    this.currentFileStream = FabricFile.Open(
                        valueCheckpointFile,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read,
                        4096,
                        FileOptions.Asynchronous);

                    // Send the start of file operation data.
                    this.perfCounterWriter.StartMeasurement();
                    bytesRead = await this.currentFileStream.ReadAsync(this.copyDataBuffer, 0, CopyChunkSize, cancellationToken).ConfigureAwait(false);

                    this.perfCounterWriter.StopMeasurement(bytesRead);

                    using (var stream = new MemoryStream(this.copyDataBuffer, writable: true))
                        using (var writer = new BinaryWriter(stream))
                        {
                            stream.Position = bytesRead;
                            writer.Write((int)this.copySnapshotOfMetadataTableEnumerator.Current.Value.FileId);
                        }

                    this.copyDataBuffer[bytesRead + sizeof(int)] = (byte)TStoreCopyOperation.StartValueFile;
                    FabricEvents.Events.CopyAsync(
                        this.traceType,
                        string.Format(System.Globalization.CultureInfo.InvariantCulture, "StartValueFile. file:{0} bytes:{1} totalFileSize:{2}", shortFileName, bytesRead + sizeof(int) + 1, this.currentFileStream.Length));
                    return(new OperationData(new ArraySegment <byte>(this.copyDataBuffer, 0, bytesRead + sizeof(int) + 1)));
                }

                // The start of the current file was sent.  Check if there are more chunks to be sent (if the stream is at the end, this will return zero).
                this.perfCounterWriter.StartMeasurement();
                bytesRead = await this.currentFileStream.ReadAsync(this.copyDataBuffer, 0, CopyChunkSize, cancellationToken);

                this.perfCounterWriter.StopMeasurement(bytesRead);

                if (bytesRead > 0)
                {
                    this.copyDataBuffer[bytesRead] = (byte)TStoreCopyOperation.WriteValueFile;
                    FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "WriteValueFile. file:{0} bytes:{1} Position:{2}", shortFileName, bytesRead + 1, this.currentFileStream.Position));
                    return(new OperationData(new ArraySegment <byte>(this.copyDataBuffer, 0, bytesRead + 1)));
                }

                // There is no more data in the current file.  Send the end of file marker, and prepare for the next copy stage.
                this.currentFileStream.Dispose();
                this.currentFileStream = null;

                // Check if there are more files.
                if (this.copySnapshotOfMetadataTableEnumerator.MoveNext())
                {
                    // More files.
                    this.copyStage = CopyStage.KeyFile;
                }
                else
                {
                    // No more files to be sent.
                    this.copyStage = CopyStage.Complete;
                }

                // Send the end of file operation data.
                var endFileData = new ArraySegment <byte>(new[] { (byte)TStoreCopyOperation.EndValueFile });
                FabricEvents.Events.CopyAsync(this.traceType, string.Format(System.Globalization.CultureInfo.InvariantCulture, "EndValueFile. file:{0}", shortFileName));
                return(new OperationData(endFileData));
            }

            // Finally, send the "copy completed" marker.
            if (this.copyStage == CopyStage.Complete)
            {
                this.perfCounterWriter.UpdatePerformanceCounters();

                // Next copy stage.
                this.copyStage = CopyStage.None;

                // Indicate the copy operation is complete.
                FabricEvents.Events.CopyAsync(
                    this.traceType,
                    string.Format(
                        System.Globalization.CultureInfo.InvariantCulture,
                        "completed. directory:{0}, diskread:{1}bytes/sec",
                        directory,
                        this.perfCounterWriter.AvgDiskTransferBytesPerSec));
                var copyCompleteData = new ArraySegment <byte>(new[] { (byte)TStoreCopyOperation.Complete });
                return(new OperationData(copyCompleteData));
            }

            // Finished copying.  Dispose immediately to release resources/locks.
            if (!this.disposed)
            {
                ((IDisposable)this).Dispose();
            }

            return(null);
        }
示例#8
0
    public static void CreateWindow()
    {
        CopyStage window = (CopyStage)GetWindow(typeof(CopyStage));

        window.Show();
    }