Example #1
0
        public static ReplicatedTableQuorumWriteResult TryUploadBlobs <T>(List <CloudBlockBlob> blobs, T configuration)
            where T : class
        {
            string content = configuration.ToString();

            // Update blobs ...
            int numberOfBlobs = blobs.Count;

            ReplicatedTableWriteBlobResult[] writeResultArray = new ReplicatedTableWriteBlobResult[numberOfBlobs];

            Parallel.For(0, numberOfBlobs, index =>
            {
                writeResultArray[index] = TryWriteBlob(blobs[index], content, "*");
            });

            int successRate = writeResultArray.Count(e => e.Success == true);

            if (successRate == numberOfBlobs)
            {
                return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.Success, writeResultArray.ToList()));
            }

            return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.QuorumWriteFailure, writeResultArray.ToList()));
        }
Example #2
0
        public static ReplicatedTableQuorumWriteResult TryWriteBlobQuorum <T>(List <CloudBlockBlob> blobs, T configuration, Func <string, T> ParseBlobFunc, Func <T, T, bool> ConfigIdComparer, Func <T, T> GenerateConfigId)
            where T : ReplicatedTableConfigurationBase, new()
        {
            // Fetch all blobs ...
            List <T>      valuesArray;
            List <string> eTagsArray;
            List <ReplicatedTableReadBlobResult> resultArray = TryReadAllBlobs(blobs, out valuesArray, out eTagsArray, ParseBlobFunc);

            // Find majority ...
            int quorumIndex;
            ReplicatedTableQuorumReadResult majority = FindMajority(resultArray.AsReadOnly(), valuesArray.AsReadOnly(), out quorumIndex);
            string readDetails = majority.ToString();

            switch (majority.Code)
            {
            case ReplicatedTableQuorumReadCode.NotFound:
                // Create blobs ...
                break;

            case ReplicatedTableQuorumReadCode.UpdateInProgress:
                return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.ConflictDueToUpdateInProgress, readDetails));

            case ReplicatedTableQuorumReadCode.Exception:
                return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.ReadExceptions, readDetails));

            case ReplicatedTableQuorumReadCode.NullOrLowSuccessRate:
                return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.ReadNoQuorum, readDetails));

            case ReplicatedTableQuorumReadCode.Success:
                // Blob has changed since ...
                if (ConfigIdComparer(valuesArray[quorumIndex], configuration) == false)
                {
                    return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.ConflictDueToBlobChange, readDetails));
                }

                // Update blobs ...
                break;

            case ReplicatedTableQuorumReadCode.BlobsNotInSyncOrTransitioning:
                return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.BlobsNotInSyncOrTransitioning, readDetails));

            case ReplicatedTableQuorumReadCode.NullObject:
            default:
            {
                var msg = string.Format("Unexpected value majority=\'{0}\' ", majority.Code);
                throw new Exception(msg);
            }
            }

            // Generate a new Id for the copy of the input configuration
            T      newConfiguration = GenerateConfigId(configuration);
            string content          = newConfiguration.ToString();

            // Update blobs ...
            int numberOfBlobs = blobs.Count;

            ReplicatedTableWriteBlobResult[] writeResultArray = new ReplicatedTableWriteBlobResult[numberOfBlobs];

            Parallel.For(0, numberOfBlobs, index =>
            {
                T currentValue     = valuesArray[index];
                string currentETag = eTagsArray[index];

                if (currentValue == null)
                {
                    currentETag = null;
                }
                else if (!ConfigIdComparer(currentValue, configuration))
                {
                    currentETag = "*";
                }

                writeResultArray[index] = TryWriteBlob(blobs[index], content, currentETag);
            });

            int successRate = writeResultArray.Count(e => e.Success == true);
            int quorum      = (numberOfBlobs / 2) + 1;

            if (successRate >= quorum)
            {
                // Return new config Id to the caller for record
                string newConfId = newConfiguration.GetConfigId().ToString();
                return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.Success, newConfId, writeResultArray.ToList()));
            }

            return(new ReplicatedTableQuorumWriteResult(ReplicatedTableQuorumWriteCode.QuorumWriteFailure, writeResultArray.ToList()));
        }