/// <summary> /// Write a single state provider metadata to the stream. /// </summary> /// <param name="writer">Stream to write to.</param> /// <param name="metadata">State provider metadata to serialize.</param> /// <returns>The record size written.</returns> private static int WriteMetadata(InMemoryBinaryWriter writer, SerializableMetadata metadata) { var startPosition = writer.BaseStream.Position; // Reserve an 'int' for the record size at the beginning. writer.BaseStream.Position += sizeof(int); // Serialize the metadata. writer.Write(metadata.Name); writer.Write(metadata.Type); writer.Write(metadata.CreateLsn); writer.Write(metadata.DeleteLsn); writer.WriteNullable(metadata.InitializationContext); writer.Write((int)metadata.MetadataMode); writer.Write(metadata.StateProviderId); writer.Write(metadata.ParentStateProviderId); // Get the size of the record. var endPosition = writer.BaseStream.Position; var recordSize = checked ((int)(endPosition - startPosition)); // Write the record size at the start of the block. writer.BaseStream.Position = startPosition; writer.Write(recordSize); // Restore the end position. writer.BaseStream.Position = endPosition; return(recordSize); }
/// <summary> /// Create the header for the OperationData /// </summary> internal OperationData CreateContext() { OperationData context; const int streamSize = sizeof(int) // version + sizeof(long) // stateProviderId + sizeof(bool); // boolean indicating if the state provider data is null. using (InMemoryBinaryWriter writer = new InMemoryBinaryWriter(new MemoryStream(streamSize))) { writer.Write(this.Version); writer.Write(this.StateProviderId); writer.Write(this.OperationData == null); Utility.Assert( writer.BaseStream.Position == streamSize, "{0}: CreateContext: Size is not correct, Position: {1}.", this.TraceType, writer.BaseStream.Position); context = new OperationData(new ArraySegment <byte>( writer.BaseStream.GetBuffer(), 0, checked ((int)writer.BaseStream.Position))); } return(context); }
/// <summary> /// Write the state provider metadata to the output stream. /// </summary> /// <param name="outputstream">Output stream.</param> /// <param name="metadataList">The state providers' metadata.</param> /// <param name="cancellationToken">Token used to signal cancellation.</param> /// <returns>Task that represents the asynchronous operation.</returns> private async Task <StateManagerFileBlocks> WriteMetadataAsync( Stream outputstream, IEnumerable <SerializableMetadata> metadataList, CancellationToken cancellationToken) { // Track blocks of records, to improve sequential reads. var recordBlockSizes = new List <int>(); var recordBlockSize = 0; using (var itemStream = new MemoryStream(DesiredBlockSize * 2)) using (var itemWriter = new InMemoryBinaryWriter(itemStream)) { foreach (var metadata in metadataList) { // Write each state provider metadata into the memory stream. var recordPosition = checked ((int)itemStream.Position); var recordSize = WriteMetadata(itemWriter, metadata); // Checksum this metadata record (with the record size included). var recordChecksum = CRC64.ToCRC64(itemStream.GetBuffer(), recordPosition, recordSize); // Add the checksum at the end of the memory stream. itemWriter.Write(recordChecksum); // Track record block sizes. After enough bytes are buffered in memory, flush to disk. recordBlockSize = checked ((int)itemStream.Position); if (recordBlockSize >= DesiredBlockSize) { // Flush the metadata records to the output stream. await outputstream.WriteAsync(itemStream.GetBuffer(), 0, recordBlockSize, cancellationToken).ConfigureAwait(false); recordBlockSizes.Add(recordBlockSize); itemStream.Position = 0; } // Update properties. this.Properties.StateProviderCount++; if (metadata.ParentStateProviderId == DynamicStateManager.EmptyStateProviderId) { this.Properties.RootStateProviderCount++; } } // Flush any remaining bytes to disk, and add the last record block size (if any). recordBlockSize = checked ((int)itemStream.Position); if (recordBlockSize > 0) { await outputstream.WriteAsync(itemStream.GetBuffer(), 0, recordBlockSize, cancellationToken).ConfigureAwait(false); recordBlockSizes.Add(recordBlockSize); } } // Return the record block sizes. var blocks = new StateManagerFileBlocks(recordBlockSizes.ToArray()); return(blocks); }
/// <summary> /// Gets the next chunk of copy data from the in-memory state provider metadata enumerator. /// </summary> /// <param name="stateEnumerator">State provider metadata enumerator.</param> /// <param name="traceType">Tracing type information.</param> /// <returns>The next chunk of copy data.</returns> internal static IEnumerable <OperationData> GetCopyData( IEnumerator <SerializableMetadata> stateEnumerator, string traceType) { var metadataCount = 0; // Create a single re-usable memory stream for Copy. using (var itemStream = new MemoryStream(DesiredBlockSize)) using (var itemWriter = new InMemoryBinaryWriter(itemStream)) { // Send the copy operation protocol version number first. itemWriter.Write(CopyProtocolVersion); itemWriter.Write((byte)StateManagerCopyOperation.Version); yield return (new OperationData( new ArraySegment <byte>(itemStream.GetBuffer(), 0, checked ((int)itemStream.Position)))); // Send the state provider metadata in chunks. itemStream.Position = 0; while (stateEnumerator.MoveNext()) { WriteMetadata(itemWriter, stateEnumerator.Current); metadataCount++; if (itemStream.Position >= DesiredBlockSize) { // Send a chunk of state provider metadata. itemWriter.Write((byte)StateManagerCopyOperation.StateProviderMetadata); yield return (new OperationData( new ArraySegment <byte>(itemStream.GetBuffer(), 0, checked ((int)itemStream.Position)))); // Reset the item memory stream for the next chunk. itemStream.Position = 0; } } // Send the last chunk, if any exists. if (itemStream.Position > 0) { itemWriter.Write((byte)StateManagerCopyOperation.StateProviderMetadata); yield return (new OperationData( new ArraySegment <byte>(itemStream.GetBuffer(), 0, checked ((int)itemStream.Position)))); } // End of Copy. FabricEvents.Events.StateManagerCopyStreamGetNext(traceType, metadataCount); } }
public static void SerializeRedoData( ReplicationMetadata replicationMetadata, string traceType, InMemoryBinaryWriter writer) { try { writer.Write(replicationMetadata.Type); writer.WriteNullable(replicationMetadata.InitializationContext); writer.Write(replicationMetadata.ParentStateProviderId); } catch (Exception e) { StateManagerStructuredEvents.TraceException(traceType, "ReplicationMetadata.Serialize", string.Empty, e); throw; } }
/// <summary> /// Serializes replication metadata. /// </summary> public static void SerializeMetaData( ReplicationMetadata replicationMetadata, string traceType, InMemoryBinaryWriter writer) { try { writer.Write(replicationMetadata.Version); writer.Write(replicationMetadata.StateProviderId); writer.Write(replicationMetadata.Name); writer.Write((byte)replicationMetadata.StateManagerApplyType); } catch (Exception e) { StateManagerStructuredEvents.TraceException(traceType, "ReplicationMetadata.Serialize", string.Empty, e); throw; } }