Exemplo n.º 1
0
        public void respondIfNewNode(String machineName, String sellerName, Uri machine)
        {
            // Clear the cache because the system changed -> the data changed
            cache.clear();

            //Barrier - Create, Enter, BLOCK -> Leave when Balancing ends
            var barrier = AirlineReplicationModule.Instance.barrier();

            // Get the cuurent snapshot of the system - including the new machine that came up!
            //not included the sellers that it holds.
            Dictionary <string, ZNodesDataStructures.MachineNode> machines = AirlineReplicationModule.Instance.Machines;

            // in the ZK tree: If a machine holds a seller that has return to live - drop it!
            foreach (string smachine in machines.Keys)
            {
                if (!smachine.Equals(machineName))
                {
                    machines[smachine].primaryOf.Remove(sellerName);
                    machines[smachine].backsUp.Remove(sellerName);
                }
            }

            // this is the oldest legal view of the tree. necessary to enable sellers transfers
            Dictionary <string, ZNodesDataStructures.MachineNode> machinesOldVersion = copyMachines(machines);

            // in the local data: If a this machine holds an old version of the seller - drop it!!
            if (!machineName.Equals(myName))
            {
                primaries.RemoveAll(delegate(Seller candidate)
                {
                    return(candidate.name.Equals(sellerName));
                });

                backups.RemoveAll(delegate(Seller candidate)
                {
                    return(candidate.name.Equals(sellerName));
                });
            }

            // the new machine holds the new seller
            // If there is only a single machine there is no need to backup the seller and load balancing
            if (machines.Count == 1)
            {
                try
                {
                    ServiceEndpoint sellerSearchEndPoint =
                        new ServiceEndpoint(ContractDescription.GetContract(
                                                typeof(IAirSellerRegisteration)),
                                            new WebHttpBinding(),
                                            new EndpointAddress
                                                (mysearchServerAddress));
                    using (WebChannelFactory <IAirSellerRegisteration> cf = new WebChannelFactory <IAirSellerRegisteration>(sellerSearchEndPoint))
                    {
                        IAirSellerRegisteration registerChannel = cf.CreateChannel();
                        //Register the channel in the server
                        registerChannel.RegisterSeller(new Uri(myAddress), clusterName);
                    }
                }
                catch (ProtocolException e)
                {
                    Console.WriteLine("Bad Protocol: " + e.Message);
                }
                catch (Exception e)
                {
                    if (e.InnerException is WebException)
                    {
                        HttpWebResponse resp = (HttpWebResponse)((WebException)e.InnerException).Response;
                        Console.WriteLine("Failed, {0}", resp.StatusDescription);
                    }
                    else
                    {
                        Console.WriteLine("Advertisement connection kicked the bucket, quitting because:");
                        Console.WriteLine(e.Message.ToString());
                    }
                    return;
                }
            }
            else
            {
                // if there are 2 machines - it means that before the current machine has joined there were no backups!
                if (machines.Count == 2)
                {
                    // get the oldest machine
                    string oldMachine = machines.Keys.Where(delegate(string str)
                    {
                        return(!str.Equals(machineName));
                    }).First();

                    // backup all the sellers in the old machine
                    foreach (string sell in machines[oldMachine].primaryOf)
                    {
                        machines[machineName].backsUp.Add(sell);
                        if (machineName.Equals(myName))
                        {
                            ServiceEndpoint endPoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(ISellerClusterService)), new BasicHttpBinding(), new EndpointAddress(machines[oldMachine].uri));
                            using (ChannelFactory <ISellerClusterService> httpFactory = new ChannelFactory <ISellerClusterService>(endPoint))
                            {
                                ISellerClusterService sellerCluster = httpFactory.CreateChannel();
                                try
                                {
                                    Seller sellerToBackup = sellerCluster.sendPrimarySeller(sell);
                                    if (sellerToBackup == null)
                                    {
                                        sellerToBackup = sellerCluster.sendBackupSeller(sellerName);
                                    }
                                    backups.Add(sellerToBackup);
                                }
                                catch (FaultException fe)
                                {
                                    Console.WriteLine("Failure in getting seller. Because: " + fe.Message);
                                    return;
                                }
                            }
                        }
                    }
                }

                // find a deterministic victim to hold the backup of the new seller
                string victim = (from p in machines where !p.Key.Equals(machineName) orderby p.Value.primaryOf.Count ascending, p.Key ascending select p.Key).First();

                // if the victim is this machine - follow the command and ask a clone from the new machine that owns the primary replica
                if (victim.Equals(myName))
                {
                    Uri uri = machine;

                    ServiceEndpoint endPoint = new ServiceEndpoint(
                        ContractDescription.GetContract(typeof(ISellerClusterService)), new BasicHttpBinding(), new EndpointAddress(machines[machineName].uri));
                    using (ChannelFactory <ISellerClusterService> httpFactory = new ChannelFactory <ISellerClusterService>(endPoint))
                    {
                        ISellerClusterService sellerCluster = httpFactory.CreateChannel();
                        try
                        {
                            Seller sellerToBackup = sellerCluster.sendPrimarySeller(sellerName);
                            if (sellerToBackup == null)
                            {
                                sellerToBackup = sellerCluster.sendBackupSeller(sellerName);
                            }
                            backups.Add(sellerToBackup);
                        }
                        catch (FaultException fe)
                        {
                            Console.WriteLine("Failure in getting seller. Because: " + fe.Message);
                            return;
                        }
                    }
                }
                // update it in the ZK tree
                machines[victim].backsUp.Add(sellerName);
            }

            // execute a deterministic load-balancing algorithm
            if (machines.Keys.Count > 1)
            {
                Console.WriteLine("\t** BALANCING ALGORITHM STARTED **");
                balanceTheTreeAfterJoined(machines, machinesOldVersion, machineName, machine);
                // this lock makes sure that no search server will serviced while sellers are removed from the machine.
                Console.WriteLine("\t** BALANCING ALGORITHM FINISHED **");
            }



            //// barrier: in order to prevent losing replicas at same time that other machines asks for them
            barrier.Leave();
            // update the ZK server!!
            AirlineReplicationModule.Instance.updateMachineData(machines);

            // update the primaries and backups lists - now we can remove the not needed replicas
            primaries.RemoveAll(delegate(Seller p) { return(!machines[myName].primaryOf.Contains(p.name)); });
            backups.RemoveAll(delegate(Seller p) { return(!machines[myName].backsUp.Contains(p.name)); });

            // print replicas status
            print(machines);
        }
Exemplo n.º 2
0
        public void respondIfSomeoneLeft(List <String> sellersWhoLostPrimary, List <String> sellersWhoLostBackup)
        {
            var barrier = AirlineReplicationModule.Instance.barrier();

            // If this machine is a leader: register as a delegate
            if (!isLeader && checkIfLeader())
            {
                isLeader = true;
                try
                {
                    ServiceEndpoint sellerSearchEndPoint =
                        new ServiceEndpoint(ContractDescription.GetContract(
                                                typeof(IAirSellerRegisteration)),
                                            new WebHttpBinding(),
                                            new EndpointAddress
                                                (mysearchServerAddress));
                    using (WebChannelFactory <IAirSellerRegisteration> cf = new WebChannelFactory <IAirSellerRegisteration>(sellerSearchEndPoint))
                    {
                        IAirSellerRegisteration registerChannel = cf.CreateChannel();
                        //Register the channel in the server
                        registerChannel.RegisterSeller(new Uri(myAddress), clusterName);
                    }
                }
                catch (ProtocolException e)
                {
                    Console.WriteLine("Bad Protocol: " + e.Message);
                }
                catch (Exception e)
                {
                    if (e.InnerException is WebException)
                    {
                        HttpWebResponse resp = (HttpWebResponse)((WebException)e.InnerException).Response;
                        Console.WriteLine("Failed, {0}", resp.StatusDescription);
                    }
                    else
                    {
                        Console.WriteLine("Advertisement connection kicked the bucket, quitting because:");
                        Console.WriteLine(e.Message.ToString());
                    }
                    return;
                }
            }

            // get the updated snapshot
            Dictionary <string, ZNodesDataStructures.MachineNode> machines           = AirlineReplicationModule.Instance.Machines;
            Dictionary <string, ZNodesDataStructures.MachineNode> machinesOldVersion = copyMachines(machines);

            Console.WriteLine("\t** BALANCING ALGORITHM STARTED **");
            // execute a deterministic load-balancing algorithm - and also fill the machines with backup nodes
            balanceTheTreeAfterLeft(machines, machinesOldVersion, sellersWhoLostBackup, sellersWhoLostPrimary);
            Console.WriteLine("\t** BALANCING ALGORITHM FINISHED **");


            //Barrier
            barrier.Leave();

            AirlineReplicationModule.Instance.updateMachineData(machines);

            primaries.RemoveAll(delegate(Seller s) { return(!machines[myName].primaryOf.Contains(s.name)); });

            backups.RemoveAll(delegate(Seller s) { return(!machines[myName].backsUp.Contains(s.name)); });

            print(machines);
        }