public LocationConstraint(string containerName, ReplicaConfiguration currentConfig, string serverName, LocationConstraintType type)
     : base(containerName, currentConfig)
 {
     this.Type = type;
     this.ConstrainedContainer = ClientRegistry.GetCloudBlobContainer(serverName, containerName);
     this.ServerName           = serverName;
 }
        internal ConfigurationAction(string containerName, string serverName, float?utility, string SLAId = null, ConfigurationActionSource source = ConfigurationActionSource.NonConstraint, int numberOfReads = 0, int numberOfWrites = 0)
        {
            this.Configuration      = ClientRegistry.GetConfiguration(containerName, false);
            this.ModifyingContainer = ClientRegistry.GetCloudBlobContainer(serverName, containerName);
            this.GainedUtility      = utility ?? 0;
            OriginatingSLAs         = new HashSet <string>();
            Clients = new HashSet <string>();
            if (SLAId != null)
            {
                OriginatingSLAs.Add(SLAId);
            }

            this.Source         = source;
            this.numberOfReads  = numberOfReads;
            this.numberOfWrites = numberOfWrites;
            this.ServerName     = serverName;

            if (numberOfBlobs == 0)
            {
                CloudBlobContainer primaryContainer = ClientRegistry.GetCloudBlobContainer(Configuration.PrimaryServers.First(), containerName);
                numberOfBlobs = primaryContainer.ListBlobs().Count();
            }

            Cost = ComputeCost();
        }
Пример #3
0
        public override void Execute()
        {
            CloudBlobContainer   primaryContainer = ClientRegistry.GetCloudBlobContainer(Configuration.PrimaryServers.First(), ModifyingContainer.Name);
            SynchronizeContainer synchronizer     = new SynchronizeContainer(primaryContainer, ModifyingContainer);

            synchronizer.BeginSyncContainers();

            Configuration.EndCurrentEpoch();

            Configuration.PrimaryServers.Add(ServerName);

            //we add the new primary also to the list of write_only primaries.
            //Servers in this list are not registered in session state, hence a get operation cannot be issued for them.
            //This makes put operations to go to all primaries (including the new one), but get_primary only goes to old primaries (those that does not exist in not register list).
            Configuration.WriteOnlyPrimaryServers.Add(ServerName);

            Configuration.StartNewEpoch();

            //We wait until sync is finihsed
            synchronizer.EndSyncContainers();

            // TODO: check that the new primary server did indeed get all of the writes.

            Configuration.EndCurrentEpoch();

            //We clear the not register primary list, so the new primary can also be registered and used for get_primary operations.
            Configuration.WriteOnlyPrimaryServers.Clear();

            //Finally, we update the lookup service by writing the new configuration to the cloud, so every other client can read it.
            Configuration.StartNewEpoch();
        }
        public override void Execute()
        {
            if (!Configuration.PrimaryServers.Contains(ServerName))
            {
                AppendToLogger("Start Asynchronous Synchronization.");
                CloudBlobContainer   primaryContainer = ClientRegistry.GetCloudBlobContainer(Configuration.PrimaryServers.First(), ModifyingContainer.Name);
                SynchronizeContainer synchronizer     = new SynchronizeContainer(primaryContainer, ModifyingContainer);
                // let's try avoiding asynchronous sync to see if that makes things run faster
                // synchronizer.BeginSyncContainers();

                AppendToLogger("Ending Epoch " + Configuration.Epoch);
                Configuration.EndCurrentEpoch();

                Configuration.PrimaryServers.Add(ServerName);

                //add the new primary also to the list of write_only primaries.
                //Servers in this list are not registered in session state, hence a get operation cannot be issued for them.
                //This makes put operations to go to all primaries (including the new one), but get_primary only goes to old primaries (those that does not exist in not register list).
                Configuration.WriteOnlyPrimaryServers.Add(ServerName);

                AppendToLogger("Starting the new Epoch");
                Configuration.StartNewEpoch();

                //wait until sync is finihsed
                AppendToLogger("Wait to finish Synchronization");
                // synchronizer.EndSyncContainers();
                synchronizer.SyncContainers();
            }

            AppendToLogger("Synchronization finished. Ending current epoch again.");
            Configuration.EndCurrentEpoch();

            //clear the not registered primary list, so the new primary can also be registered and used for get_primary operations.
            Configuration.WriteOnlyPrimaryServers.Clear();

            //all primaries will become secondaries, hence they are added to secondary list, and their sync period is set.
            Configuration.PrimaryServers.ForEach(s => { if (!s.Equals(ServerName))
                                                        {
                                                            Configuration.SecondaryServers.Add(s);
                                                        }
                                                        Configuration.SetSyncPeriod(s, ConstPool.DEFAULT_SYNC_INTERVAL); });
            Configuration.PrimaryServers.Clear();

            //new primary is added to primary list.
            Configuration.PrimaryServers.Add(ServerName);

            //if the new primary has been a secondary, it is removed from the secondary list.
            if (Configuration.SecondaryServers.Contains(ServerName))
            {
                Configuration.SecondaryServers.Remove(ServerName);
            }

            //Finally, update the lookup service by writing the new configuration to the cloud, so every other client can read it.
            AppendToLogger("Starting the new Epoch with One Primary");
            Configuration.StartNewEpoch();
        }
Пример #5
0
        /// <summary>
        /// Pings all servers to obtain their round-trips times and their high timestamps.
        /// </summary>
        public void PingTimestampsNow()
        {
            Stopwatch watch = new Stopwatch();

            foreach (string server in configuration.SecondaryServers)
            {
                // if the server is not reached yet, we perform a dummy operation for it.
                if (!replicas[server].IsContacted())
                {
                    try
                    {
                        //we perform a dummy operation to get the rtt latency!
                        DateTimeOffset?serverTime = null;
                        long           rtt;
                        if (server.EndsWith("-secondary") && configuration.PrimaryServers.Contains(server.Replace("-secondary", "")))
                        {
                            // get the server's last sync time from Azure
                            // this call only works on Azure secondaries
                            CloudBlobClient blobClient = ClientRegistry.GetCloudBlobClient(server);
                            watch.Restart();
                            ServiceStats stats = blobClient.GetServiceStats();
                            rtt = watch.ElapsedMilliseconds;
                            replicas[server].AddRtt(rtt);
                            if (stats.GeoReplication.LastSyncTime.HasValue)
                            {
                                serverTime = stats.GeoReplication.LastSyncTime.Value;
                            }
                        }
                        else
                        {
                            // get the server's last sync time from the container's metadata
                            CloudBlobContainer blobContainer = ClientRegistry.GetCloudBlobContainer(server, configuration.Name);
                            watch.Restart();
                            blobContainer.FetchAttributes();
                            rtt = watch.ElapsedMilliseconds;
                            if (blobContainer.Metadata.ContainsKey("lastsync"))
                            {
                                //if no lastmodified time is provided in the constructor, we still try to be fast.
                                //So, we check to see if by any chance the container previously has synchronized.
                                serverTime = DateTimeOffset.Parse(blobContainer.Metadata["lastsync"]);
                            }
                        }
                        if (serverTime.HasValue && serverTime > replicas[server].HighTime)
                        {
                            replicas[server].HighTime = serverTime.Value;
                        }
                    }
                    catch (StorageException)
                    {
                        // do nothing
                    }
                }
            }
        }
Пример #6
0
        public override void Execute()
        {
            AppendToLogger("Start Synchronization");
            CloudBlobContainer   primaryContainer = ClientRegistry.GetCloudBlobContainer(Configuration.PrimaryServers.First(), ModifyingContainer.Name);
            SynchronizeContainer synchronizer     = new SynchronizeContainer(primaryContainer, ModifyingContainer);

            synchronizer.SyncContainers();
            AppendToLogger("Synchronization finished.");
            //Update the configuration
            Configuration.SecondaryServers.Add(ServerName);

            AppendToLogger("Starting the new Epoch");
            Configuration.StartNewEpoch();
        }
Пример #7
0
        private static void SyncSecondaryServers()
        {
            string primarySite = config.PrimaryServers.First();

            foreach (string secondarySite in config.SecondaryServers)
            {
                if (!config.ReadOnlySecondaryServers.Contains(secondarySite))
                {
                    SynchronizeContainer synchronizer = new SynchronizeContainer(ClientRegistry.GetCloudBlobContainer(primarySite, containerName),
                                                                                 ClientRegistry.GetCloudBlobContainer(secondarySite, containerName));
                    synchronizer.SyncContainers();
                    Log("Synchronization completed to " + SiteName(secondarySite) + ".");
                }
                else
                {
                    Log("Could not sync to " + SiteName(secondarySite) + " since secondary is read-only.");
                }
            }
        }