private void StartReplicating()
        {
            Dictionary <string, SynchronizeContainer> syncing    = new Dictionary <string, SynchronizeContainer>();
            Dictionary <string, DateTimeOffset>       lastSynced = new Dictionary <string, DateTimeOffset>();
            int alreadySleep = 0;

            while (true)
            {
                if (configuration.IsInFastMode() && configuration.SecondaryServers.Count > 0)
                {
                    alreadySleep = 0;
                    syncing.Clear();

                    // compute shortest sync period
                    int sleepTime = ConstPool.DEFAULT_SYNC_INTERVAL;
                    foreach (string server in configuration.SecondaryServers)
                    {
                        if (configuration.GetSyncPeriod(server) < sleepTime)
                        {
                            sleepTime = configuration.GetSyncPeriod(server);
                        }
                    }
                    Thread.Sleep(sleepTime - alreadySleep);

                    foreach (string server in configuration.SecondaryServers)
                    {
                        //server should not exist in primary servers. This case happens during first phase of MakeSoloPrimaryServer action
                        //where a secondary server also exist in primary server set.
                        if (configuration.GetSyncPeriod(server) == sleepTime && !configuration.PrimaryServers.Contains(server))
                        {
                            Console.WriteLine("Starting to sync " + configuration.Name + " with " + server);

                            DateTimeOffset?tmpOffset = null;
                            if (lastSynced.ContainsKey(server))
                            {
                                tmpOffset = lastSynced[server];
                            }
                            lastSynced[server] = DateTimeOffset.Now;
                            SynchronizeContainer synchronizer = new SynchronizeContainer(ClientRegistry.GetMainPrimaryContainer(name), ClientRegistry.GetCloudBlobContainer(server, name), tmpOffset);
                            synchronizer.BeginSyncContainers();
                            syncing[server] = synchronizer;
                        }
                    }
                    foreach (string syncedServer in syncing.Keys)
                    {
                        syncing[syncedServer].EndSyncContainers();
                    }
                    Console.WriteLine("Finished synchronization. ");
                    alreadySleep = sleepTime;
                }
                else
                {
                    lock (configuration)
                        Monitor.Wait(configuration, ConstPool.CONFIGURATION_ACTION_DURATION);
                }
            }
        }
        /// <summary>
        /// Read the configuration blob from Azure storage and update the local configuration.
        /// </summary>
        internal bool DownloadConfiguration()
        {
            try
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    configurationBlob.DownloadToStream(stream);
                    stream.Seek(0, 0);
                    BinaryFormatter      formatter   = new BinaryFormatter();
                    ReplicaConfiguration cloudConfig = (ReplicaConfiguration)formatter.Deserialize(stream);

                    if (!configurationBlob.Metadata.ContainsKey(ConstPool.EPOCH_NUMBER))
                    {
                        Console.WriteLine("No Epoch in configuration metadata!"); // this should not happen
                        return(false);                                            // stay with current configuration for now
                    }

                    int currentEpoch = Convert.ToInt32(configurationBlob.Metadata[ConstPool.EPOCH_NUMBER]);
                    if (currentEpoch > config.Epoch)
                    {
                        config.PrimaryServers = cloudConfig.PrimaryServers;
                        config.PrimaryServers.Sort();
                        config.SecondaryServers        = cloudConfig.SecondaryServers ?? new List <string>();
                        config.WriteOnlyPrimaryServers = cloudConfig.WriteOnlyPrimaryServers ?? new List <string>();
                        foreach (string server in config.SecondaryServers)
                        {
                            config.SetSyncPeriod(server, cloudConfig.GetSyncPeriod(server));
                        }

                        config.Epoch = currentEpoch;
                        if (configurationBlob.Metadata[ConstPool.EPOCH_MODIFIED_TIME] != null)
                        {
                            config.EpochModifiedTime = DateTimeOffset.Parse(configurationBlob.Metadata[ConstPool.EPOCH_MODIFIED_TIME]);
                        }
                        else
                        {
                            config.EpochModifiedTime = DateTimeOffset.MinValue;
                        }
                    }
                }
            }
            catch (StorageException se)
            {
                Console.WriteLine(se.ToString());
                Console.WriteLine(se.StackTrace);
                throw se;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.WriteLine(ex.StackTrace);
                throw ex;
            }
            return(true);
        }
        // Returns the likelihood that a given server is sufficiently up-to-date to meet the given consistency
        // For many consistencies, this is hard to predict, and better predicitve models are possible.
        public float ProbabilityOfServerConsistency(ReplicaConfiguration config, string server, Consistency consistency, int bound)
        {
            float prob = 0;

            switch (consistency)
            {
            case Consistency.Strong:
                if (config.PrimaryServers.Contains(server) && !config.WriteOnlyPrimaryServers.Contains(server))
                {
                    prob = 1.0F;
                }
                break;

            case Consistency.ReadMyWrites:
            case Consistency.Session:
                // could possibly compute probability based on past performance and read/write ratio
                // for now, arbitrarily return 0.5
                prob = 0.5F;
                break;

            case Consistency.MonotonicReads:
                // almost always will read from the closest server
                prob = 1.0F;
                break;

            case Consistency.Causal:
                // could possibly compute probability based on past performance and read/write ratio
                // for now, arbitrarily return 0.25
                prob = 0.25F;
                break;

            case Consistency.Bounded:
            case Consistency.BoundedMonotonicReads:
                // depends on the sync frequency
                if (bound >= config.GetSyncPeriod(server))
                {
                    prob = 1.0F;
                }
                else
                {
                    prob = bound / config.GetSyncPeriod(server);
                }
                break;

            case Consistency.BoundedReadMyWrites:
            case Consistency.BoundedSession:
                // depends on the sync frequency
                if (bound >= config.GetSyncPeriod(server))
                {
                    prob = 0.5F;
                }
                else
                {
                    prob = bound / config.GetSyncPeriod(server);
                }
                break;

            case Consistency.Eventual:
                if (config.PrimaryServers.Contains(server) || config.SecondaryServers.Contains(server))
                {
                    prob = 1.0F;
                }
                break;

            default:
                prob = 0;
                break;
            }

            return(prob);
        }