コード例 #1
0
ファイル: View.cs プロジェクト: srinathsetty/rtable
        public static View InitFromConfigVer2(string name, ReplicatedTableConfigurationStore configurationStore, Action <ReplicaInfo> SetConnectionString)
        {
            View view = new View(name);

            if (configurationStore != null)
            {
                view.ViewId = configurationStore.ViewId;

                foreach (ReplicaInfo replica in configurationStore.GetCurrentReplicaChain())
                {
                    SetConnectionString(replica);

                    CloudTableClient tableClient = ReplicatedTableConfigurationManager.GetTableClientForReplica(replica);
                    if (tableClient == null)
                    {
                        // All replicas MUST exist or View is not relevant
                        view.Chain.Clear();

                        ReplicatedTableLogger.LogError("ViewName={0} could not load replica ({1})", name, replica);
                        break;
                    }

                    view.Chain.Add(new Tuple <ReplicaInfo, CloudTableClient>(replica, tableClient));
                }

                // Infered: first readable replica
                view.ReadHeadIndex = view.Chain.FindIndex(tuple => tuple.Item1.IsReadable());
            }

            return(view);
        }
コード例 #2
0
        private void ThrowIfAnyPartitionViewHasManyReplicasInConversionMode(ReplicatedTableConfiguredTable config)
        {
            if (config.ConvertToRTable == false || config.PartitionsToViewMap == null)
            {
                return;
            }

            /*
             * Key = "" - View = ""          => Ignore
             * Key = "" - View = "viewName"  => Ignore
             * Key = "X" - View = ""         => Should never happen (already tken care by the flow)
             * Key = "Y" - View = "viewName" => 'viewName' can't have more than 1 replica
             */
            foreach (var entry in config.PartitionsToViewMap.Where(e => !string.IsNullOrEmpty(e.Key)))
            {
                string viewName = entry.Value;

                ReplicatedTableConfigurationStore viewConfig = GetView(viewName);
                // Assert (viewConfig != null)

                // In Conversion mode, view should not have more than 1 replica
                List <ReplicaInfo> chainList = viewConfig.GetCurrentReplicaChain();
                if (chainList.Count <= 1)
                {
                    continue;
                }

                var msg = string.Format("Table:\'{0}\' refers a partition view:\'{1}\' with more than 1 replica while in Conversion mode!",
                                        config.TableName,
                                        viewName);
                throw new Exception(msg);
            }
        }
コード例 #3
0
        private void ThrowIfViewBreaksTableConstraint(string viewName, ReplicatedTableConfigurationStore config)
        {
            foreach (ReplicatedTableConfiguredTable table in tableList)
            {
                if (table.ConvertToRTable == false || !table.IsViewReferenced(viewName))
                {
                    continue;
                }

                // Conversion mode: view shoud not have more than 1 replica
                List <ReplicaInfo> chainList = config.GetCurrentReplicaChain();
                if (chainList.Count <= 1)
                {
                    continue;
                }

                var msg = string.Format("Table:\'{0}\' should not have a view:\'{1}\' with more than 1 replica since it is in Conversion mode!",
                                        table.TableName,
                                        viewName);
                throw new Exception(msg);
            }
        }
コード例 #4
0
ファイル: View.cs プロジェクト: isabella232/rtable
        public static View InitFromConfigVer2(string name, ReplicatedTableConfigurationStore configurationStore, Action <ReplicaInfo> SetConnectionString)
        {
            View view = new View(name);

            if (configurationStore != null)
            {
                view.ViewId      = configurationStore.ViewId;
                view.RefreshTime = DateTime.UtcNow;

                foreach (ReplicaInfo replica in configurationStore.GetCurrentReplicaChain())
                {
                    SetConnectionString(replica);

                    CloudTableClient tableClient = ReplicatedTableConfigurationManager.GetTableClientForReplica(replica);
                    if (tableClient == null)
                    {
                        // All replicas MUST exist or View is not relevant
                        view.Chain.Clear();

                        ReplicatedTableLogger.LogError("ViewName={0} could not load replica ({1})", name, replica);
                        break;
                    }

                    view.Chain.Add(new Tuple <ReplicaInfo, CloudTableClient>(replica, tableClient));
                }

                // Infered: first readable replica
                view.ReadHeadIndex = view.Chain.FindIndex(tuple => tuple.Item1.IsReadable());

                // If not configured use Tail. Chain must be defined at this point, so don't move this code up!
                view.ReadTailIndex = configurationStore.ReadViewTailIndex;
                if (view.ReadTailIndex < 0)
                {
                    view.ReadTailIndex = view.TailIndex;
                }
            }

            return(view);
        }
コード例 #5
0
        private void ThrowIfViewHasManyReplicasInConvertionMode(ReplicatedTableConfiguredTable config)
        {
            if (config.ConvertToRTable == false || string.IsNullOrEmpty(config.ViewName))
            {
                return;
            }

            ReplicatedTableConfigurationStore viewConfig = GetView(config.ViewName);
            // Assert (viewConfig != null)

            // In Convertion mode, view should not have more than 1 replica
            List <ReplicaInfo> chainList = viewConfig.GetCurrentReplicaChain();

            if (chainList.Count <= 1)
            {
                return;
            }

            var msg = string.Format("Table:\'{0}\' refers a view:\'{1}\' with more than 1 replica while in Convertion mode!",
                                    config.TableName,
                                    config.ViewName);

            throw new Exception(msg);
        }
コード例 #6
0
        private void ThrowIfViewIsNotValid(string viewName, ReplicatedTableConfigurationStore config)
        {
            if (config.ReplicaChain == null || config.ReplicaChain.Any(replica => replica == null))
            {
                var msg = string.Format("View:\'{0}\' has a null replica(s) !!!", viewName);
                throw new Exception(msg);
            }

            List <ReplicaInfo> chainList = config.GetCurrentReplicaChain();

            if (chainList.Any())
            {
                /* RULE 1:
                 * =======
                 * Read replicas rule:
                 *  - [R] replicas are contiguous from Tail backwards
                 *  - [R] replica count >= 1
                 */
                string readPattern = "^W*R+$";

                /* RULE 2:
                 * =======
                 * Write replicas rule:
                 *  - [W] replicas are contiguous from Head onwards
                 *  - [W] replica count = 0 or = ChainLength
                 */
                string writePattern = "^((R+)|(W+))$";

                // Get replica sequences
                string readSeq  = "";
                string writeSeq = "";

                foreach (var replica in chainList)
                {
                    // Read sequence:
                    if (replica.IsReadable())
                    {
                        readSeq += "R";
                    }
                    else
                    {
                        readSeq += "W";
                    }

                    // Write sequence:
                    if (replica.IsWritable())
                    {
                        writeSeq += "W";
                    }
                    else
                    {
                        writeSeq += "R";
                    }
                }

                // Verify RULE 1:
                if (!Regex.IsMatch(readSeq, readPattern))
                {
                    var msg = string.Format("View:\'{0}\' has invalid Read chain:\'{1}\' !!!", viewName, readSeq);
                    throw new Exception(msg);
                }

                // Verify RULE 2:
                if (!Regex.IsMatch(writeSeq, writePattern))
                {
                    var msg = string.Format("View:\'{0}\' has invalid Write chain:\'{1}\' !!!", viewName, writeSeq);
                    throw new Exception(msg);
                }
            }
        }
コード例 #7
0
        private static void MoveReplicaToFrontAndSetViewToReadOnly(string viewName, ReplicatedTableConfigurationStore conf, string storageAccountName)
        {
            List<ReplicaInfo> list = conf.ReplicaChain;

            int matchIndex = list.FindIndex(r => r.StorageAccountName == storageAccountName);
            if (matchIndex == -1)
            {
                return;
            }

            // - Ensure its status is *None*
            ReplicaInfo candidateReplica = list[matchIndex];
            candidateReplica.Status = ReplicaStatus.None;

            // - Move it to the front of the chain
            list.RemoveAt(matchIndex);
            list.Insert(0, candidateReplica);

            // Set all active replicas to *ReadOnly*
            foreach (ReplicaInfo replica in conf.GetCurrentReplicaChain())
            {
                if (replica.Status == ReplicaStatus.WriteOnly)
                {
                    var msg = string.Format("View:\'{0}\' : can't set a WriteOnly replica to ReadOnly !!!", viewName);

                    ReplicatedTableLogger.LogError(msg);
                    throw new Exception(msg);
                }

                replica.Status = ReplicaStatus.ReadOnly;
            }

            // Update view id
            conf.ViewId++;
        }
コード例 #8
0
        private static void EnableWriteOnReplicas(string viewName, ReplicatedTableConfigurationStore conf, string storageAccountName)
        {
            List<ReplicaInfo> list = conf.ReplicaChain;

            if (!list.Any() ||
                list[0].StorageAccountName != storageAccountName)
            {
                return;
            }

            // First, enable Write on all replicas
            foreach (ReplicaInfo replica in conf.GetCurrentReplicaChain())
            {
                replica.Status = ReplicaStatus.ReadWrite;
            }

            // Then, set the head to WriteOnly
            list[0].Status = ReplicaStatus.WriteOnly;

            // one replica chain ? Force to ReadWrite
            if (conf.GetCurrentReplicaChain().Count == 1)
            {
                list[0].Status = ReplicaStatus.ReadWrite;
            }

            // Update view id
            conf.ViewId++;
        }
コード例 #9
0
        private void ThrowIfViewIsNotValid(string viewName, ReplicatedTableConfigurationStore config)
        {
            if (config.ReplicaChain == null || config.ReplicaChain.Any(replica => replica == null))
            {
                var msg = string.Format("View:\'{0}\' has a null replica(s) !!!", viewName);
                throw new Exception(msg);
            }

            List<ReplicaInfo> chainList = config.GetCurrentReplicaChain();
            if (chainList.Any())
            {
                /* RULE 1:
                 * =======
                 * Read replicas rule:
                 *  - [R] replicas are contiguous from Tail backwards
                 *  - [R] replica count >= 1
                 */
                string readPattern = "^W*R+$";

                /* RULE 2:
                 * =======
                 * Write replicas rule:
                 *  - [W] replicas are contiguous from Head onwards
                 *  - [W] replica count = 0 or = ChainLength
                 */
                string writePattern = "^((R+)|(W+))$";

                // Get replica sequences
                string readSeq = "";
                string writeSeq = "";

                foreach (var replica in chainList)
                {
                    // Read sequence:
                    if (replica.IsReadable())
                    {
                        readSeq += "R";
                    }
                    else
                    {
                        readSeq += "W";
                    }

                    // Write sequence:
                    if (replica.IsWritable())
                    {
                        writeSeq += "W";
                    }
                    else
                    {
                        writeSeq += "R";
                    }
                }

                // Verify RULE 1:
                if (!Regex.IsMatch(readSeq, readPattern))
                {
                    var msg = string.Format("View:\'{0}\' has invalid Read chain:\'{1}\' !!!", viewName, readSeq);
                    throw new Exception(msg);
                }

                // Verify RULE 2:
                if (!Regex.IsMatch(writeSeq, writePattern))
                {
                    var msg = string.Format("View:\'{0}\' has invalid Write chain:\'{1}\' !!!", viewName, writeSeq);
                    throw new Exception(msg);
                }
            }
        }
コード例 #10
0
ファイル: View.cs プロジェクト: farukc/rtable
        public static View InitFromConfigVer2(string name, ReplicatedTableConfigurationStore configurationStore, Action<ReplicaInfo> SetConnectionString)
        {
            View view = new View(name);

            if (configurationStore != null)
            {
                view.ViewId = configurationStore.ViewId;

                foreach (ReplicaInfo replica in configurationStore.GetCurrentReplicaChain())
                {
                    SetConnectionString(replica);

                    CloudTableClient tableClient = ReplicatedTableConfigurationManager.GetTableClientForReplica(replica);
                    if (tableClient != null)
                    {
                        view.Chain.Add(new Tuple<ReplicaInfo, CloudTableClient>(replica, tableClient));
                    }
                }

                // Infered: first readable replica
                view.ReadHeadIndex = view.Chain.FindIndex(tuple => tuple.Item1.IsReadable());
            }

            return view;
        }