Example #1
0
        /// <summary>
        /// Gets the next checkpoint id
        /// </summary>
        /// <returns></returns>
        private ulong GetNextCheckpoint()
        {
            var blobContainer  = _blobClient.GetContainerReference(RootContainerName);
            var checkpointBlob = WrappedPageBlob.CreateNewIfNotExists(blobContainer, CheckpointBlobName, 1);

            ((CloudPageBlob)checkpointBlob).SetSequenceNumber(SequenceNumberAction.Increment, null);
            return((ulong)((CloudPageBlob)checkpointBlob).Properties.PageBlobSequenceNumber.Value);
        }
Example #2
0
        /// <summary>
        /// Gets commits from a given blobEntry and stream id that fall within min and max revisions.
        /// </summary>
        /// <param name="bucketId">The blobEntry id to pull from.</param>
        /// <param name="streamId">The stream id.</param>
        /// <param name="minRevision">The minimum revision.</param>
        /// <param name="maxRevision">The maximum revision.</param>
        /// <returns></returns>
        public IEnumerable <ICommit> GetFrom(string bucketId, string streamId, int minRevision, int maxRevision)
        {
            var pageBlob = WrappedPageBlob.CreateNewIfNotExists(_primaryContainer, bucketId + "/" + streamId, _options.BlobNumPages);

            HeaderDefinitionMetadata headerDefinitionMetadata = null;
            var header = GetHeaderWithRetry(pageBlob, out headerDefinitionMetadata);

            // find out how many pages we are reading
            var startPage       = 0;
            var endPage         = startPage + 1;
            var startIndex      = 0;
            var numberOfCommits = 0;

            foreach (var commitDefinition in header.PageBlobCommitDefinitions)
            {
                if (minRevision > commitDefinition.Revision)
                {
                    ++startIndex;
                    startPage += commitDefinition.TotalPagesUsed;
                }
                else if (maxRevision < commitDefinition.Revision)
                {
                    break;
                }
                else
                {
                    ++numberOfCommits;
                }

                endPage += commitDefinition.TotalPagesUsed;
            }

            // download all the data
            var downloadedData = pageBlob.DownloadBytes(startPage * BlobPageSize, endPage * BlobPageSize);

            // process the downloaded data
            var commits = new List <ICommit>();

            for (var i = startIndex; i != startIndex + numberOfCommits; i++)
            {
                var commitStartIndex = (header.PageBlobCommitDefinitions[i].StartPage - startPage) * BlobPageSize;
                var commitSize       = header.PageBlobCommitDefinitions[i].DataSizeBytes;
                using (var ms = new MemoryStream(downloadedData, commitStartIndex, commitSize, false))
                {
                    var commit = _serializer.Deserialize <AzureBlobCommit>(ms);
                    commits.Add(CreateCommitFromAzureBlobCommit(commit));
                }
            }

            return(commits);
        }
Example #3
0
        /// <summary>
        /// Adds a commit to a stream.
        /// </summary>
        /// <param name="attempt">The commit attempt to be added.</param>
        /// <returns>An Commit if successful.</returns>
        public ICommit Commit(CommitAttempt attempt)
        {
            var pageBlob = WrappedPageBlob.CreateNewIfNotExists(_primaryContainer, attempt.BucketId + "/" + attempt.StreamId, _options.BlobNumPages);
            HeaderDefinitionMetadata headerDefinitionMetadata = null;
            var header = GetHeaderWithRetry(pageBlob, out headerDefinitionMetadata);

            // we must commit at a page offset, we will just track how many pages in we must start writing at
            var startPage = 0;

            foreach (var commit in header.PageBlobCommitDefinitions)
            {
                if (commit.CommitId == attempt.CommitId)
                {
                    throw new DuplicateCommitException("Duplicate Commit Attempt");
                }

                startPage += commit.TotalPagesUsed;
            }

            if (attempt.CommitSequence <= header.LastCommitSequence)
            {
                throw new ConcurrencyException("Concurrency exception in Commit");
            }

            var blobCommit =
                new AzureBlobCommit
            {
                BucketId       = attempt.BucketId,
                CommitId       = attempt.CommitId,
                CommitSequence = attempt.CommitSequence,
                CommitStampUtc = attempt.CommitStamp,
                Events         = attempt.Events.ToList(),
                Headers        = attempt.Headers,
                StreamId       = attempt.StreamId,
                StreamRevision = attempt.StreamRevision,
                Checkpoint     = GetNextCheckpoint()
            };
            var serializedBlobCommit = _serializer.Serialize(blobCommit);

            header.AppendPageBlobCommitDefinition(new PageBlobCommitDefinition(serializedBlobCommit.Length, attempt.CommitId, attempt.StreamRevision,
                                                                               attempt.CommitStamp, header.PageBlobCommitDefinitions.Count, startPage, blobCommit.Checkpoint));
            ++header.UndispatchedCommitCount;
            header.LastCommitSequence = attempt.CommitSequence;

            CommitNewMessage(pageBlob, serializedBlobCommit, header, headerDefinitionMetadata, startPage * BlobPageSize);
            return(CreateCommitFromAzureBlobCommit(blobCommit));
        }
Example #4
0
        /// <summary>
        /// Not yet implemented.
        /// </summary>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        public bool AddSnapshot(ISnapshot snapshot)
        {
            var pageBlob = WrappedPageBlob.CreateNewIfNotExists(_primaryContainer, snapshot.BucketId + "/ss/" + snapshot.StreamId, _options.BlobNumPages);

            var serializedSnapshot = _serializer.Serialize(snapshot.Payload);

            pageBlob.Metadata["ss_data_size_bytes"] = "0";
            pageBlob.Metadata["ss_stream_revision"] = "0";
            pageBlob.SetMetadata();

            var pageAlignedSize = GetPageAlignedSize(serializedSnapshot.Length);

            using (var serializedSnapshotStream = CreateAndFillStreamAligned(pageAlignedSize, serializedSnapshot))
            {
                pageBlob.Write(serializedSnapshotStream, 0, 0, new HeaderDefinitionMetadata());
            }

            pageBlob.Metadata["ss_data_size_bytes"] = serializedSnapshot.Length.ToString();
            pageBlob.Metadata["ss_stream_revision"] = snapshot.StreamRevision.ToString();
            pageBlob.SetMetadata();

            return(true);
        }