예제 #1
0
        private void LoadPathInfo(PathInfo pathInfo)
        {
            lock (loadPathInfoLock) {
                PathAccess pathFile = GetPathAccess(pathInfo.PathName);
                pathFile.SetInitialPathInfo(pathInfo);

                lock (loadPathInfoQueue) {
                    if (!loadPathInfoQueue.Contains(pathInfo)) {
                        loadPathInfoQueue.Add(pathInfo);
                    }
                }

                IServiceAddress[] rootServers = pathInfo.RootServers;

                // Poll all the root servers managing the path,
                PollAllRootMachines(rootServers);

                // Check availability,
                int availableCount = 0;
                foreach (IServiceAddress addr in rootServers) {
                    if (serviceTracker.IsServiceUp(addr, ServiceType.Root)) {
                        ++availableCount;
                    }
                }

                // Majority not available?
                if (availableCount <= (rootServers.Length/2)) {
                    Logger.Info("Majority of root servers unavailable, " +
                                "retrying loadPathInfo later");

                    // Leave the path info on the load_path_info_queue, therefore it will
                    // be retried when the root server is available again,

                    return;
                }

                Logger.Info(String.Format("loadPathInfo on path {0} at {1}", pathInfo.PathName, address));

                // Create the local data object if not present,
                pathFile.OpenLocalData();

                // Sync counter starts at 1, because we know we are self replicated.
                int syncCounter = 1;

                // Synchronize with each of the available root servers (but not this),
                foreach (IServiceAddress addr in rootServers) {
                    if (!addr.Equals(address)) {
                        if (serviceTracker.IsServiceUp(addr, ServiceType.Root)) {
                            bool success = SynchronizePathInfoData(pathFile, addr);
                            // If we successfully synchronized, increment the counter,
                            if (success) {
                                ++syncCounter;
                            }
                        }
                    }
                }

                // Remove from the queue if we successfully sync'd with a majority of
                // the root servers for the path,
                if (syncCounter > pathInfo.RootServers.Length/2) {
                    // Replay any proposals that were incoming on the path, and mark the
                    // path as synchronized/available,
                    pathFile.MarkAsAvailable();

                    lock (loadPathInfoQueue) {
                        loadPathInfoQueue.Remove(pathInfo);
                    }

                    Logger.Info(String.Format("COMPLETE: loadPathInfo on path {0} at {1}", pathInfo.PathName, address));
                }
            }
        }
예제 #2
0
        private void InitPath(PathInfo pathInfo)
        {
            IServiceAddress[] manSrvs = managerServers;

            // Fetch the path access object for the given name.
            PathAccess pathFile = GetPathAccess(pathInfo.PathName);

            IPath pathFunction;
            try {
                pathFunction = pathFile.Path;
            } catch (TypeLoadException e) {
                throw new CommitFaultException(String.Format("Type not found: {0}", e.Message));
            } catch (TypeInitializationException e) {
                throw new CommitFaultException(String.Format("Type instantiation exception: {0}", e.Message));
            } catch (AccessViolationException e) {
                throw new CommitFaultException(String.Format("Illegal Access exception: {0}", e.Message));
            }

            // Create the connection object (should be fairly lightweight)
            INetworkCache localNetCache = MachineState.GetCacheForManager(manSrvs);
            IPathConnection connection = new PathConnection(this, pathInfo, connector, manSrvs, localNetCache, serviceTracker);

            // Make an initial empty database for the path,
            // PENDING: We could keep a cached version of this image, but it's
            //   miniscule in size.
            NetworkTreeSystem treeSystem = new NetworkTreeSystem(connector, manSrvs, localNetCache, serviceTracker);
            treeSystem.NodeHeapMaxSize = 1*1024*1024;
            DataAddress emptyDbAddr = treeSystem.CreateDatabase();
            // Publish the empty state to the path,
            connection.Publish(emptyDbAddr);
            // Call the initialize function,
            pathFunction.Init(connection);
        }
예제 #3
0
        private void InternalSetPathInfo(string pathName, int pathInfoVersion, PathInfo pathInfo)
        {
            lock (pathInfoMap) {
                pathInfoMap[pathName] = pathInfo;
            }

            // Set the path info in the path access object,
            PathAccess pathFile = GetPathAccess(pathName);
            pathFile.PathInfo = pathInfo;
        }
예제 #4
0
        private DataAddress[] GetPathRootsSince(PathInfo pathInfo, DataAddress root)
        {
            // Fetch the path access object for the given name.
            PathAccess pathFile = GetPathAccess(pathInfo.PathName);

            return pathFile.GetPathRootsSince(root);
        }
예제 #5
0
 private String iGetPathStats(PathInfo pathInfo)
 {
     return iGetSnapshotStats(pathInfo, GetPathLast(pathInfo));
 }
예제 #6
0
        private void PostToPath(PathInfo pathInfo, DataAddress rootNode)
        {
            // We can't post if this service is not the root leader,
            if (!pathInfo.RootLeader.Equals(address)) {
                Logger.Error(String.Format("Failed, {0} is not root leader for {1}", address, pathInfo.PathName));
                throw new ApplicationException("Can't post update, this root service (" + address +
                                               ") is not the root leader for the path: " + pathInfo.PathName);
            }

            // Fetch the path access object for the given name.
            PathAccess pathFile = GetPathAccess(pathInfo.PathName);

            // Only allow post if complete and synchronized
            pathFile.CheckIsSynchronized();

            // Create a unique time based uid.
            long uid = CreateUID();

            // Post the data address to the path,
            pathFile.PostProposalToPath(uid, rootNode);

            // Notify all the root servers of this post,
            NotifyAllRootServersOfPost(pathInfo, uid, rootNode);
        }
예제 #7
0
        private DataAddress[] InternalGetPathHistorical(PathInfo pathInfo, IServiceAddress server,
			long timeStart, long timeEnd)
        {
            Message message = new Message("getPathHistorical", pathInfo.PathName, pathInfo.VersionNumber, timeStart, timeEnd);

            Message m = ProcessSingleRoot(message.AsStream(), server);
            if (m.HasError)
                throw new ApplicationException(m.ErrorMessage);

            return (DataAddress[]) m.Arguments[0].Value;
        }
예제 #8
0
 internal void SetInitialPathInfo(PathInfo value)
 {
     lock (accessLock) {
         if (pathInfoSet == false &&
             pathInfo == null) {
             pathInfoSet = true;
             PathInfo = value;
         }
     }
 }
예제 #9
0
            public PathConnection(RootService service, PathInfo pathInfo, IServiceConnector connector, IServiceAddress[] managerServers,
			                      INetworkCache cache, ServiceStatusTracker statusTracker)
            {
                this.service = service;
                this.pathInfo = pathInfo;
                treeSystem = new NetworkTreeSystem(connector, managerServers, cache, statusTracker);
            }
예제 #10
0
 public void SetPathInfo(string pathName, PathInfo pathInfo)
 {
     lock (pathInfoMap) {
         pathInfoMap[pathName] = pathInfo;
     }
 }
예제 #11
0
 public void SetPathInfo(string pathName, PathInfo pathInfo)
 {
     lock (pathInfoMap) {
         pathInfoMap[pathName] = pathInfo;
     }
 }
예제 #12
0
        private void OutputPathInfo(NetworkContext context, PathInfo p)
        {
            string pathName = p.PathName;

            Out.Write("+Name: ");
            Out.Write(pathName);
            Out.Write(" (");
            Out.Write(p.PathType);
            Out.WriteLine(")");

            Out.Write(" Srvs: ");
            IServiceAddress leader = p.RootLeader;
            IServiceAddress[] srvs = p.RootServers;
            foreach (IServiceAddress srv in srvs) {
                bool il = srv.Equals(leader);
                if (il)
                    Out.Write("[");
                Out.Write(srv.ToString());
                if (il)
                    Out.Write("*]");
                Out.Write(" ");
            }
            Out.WriteLine();

            Out.Write(" Status: ");
            try {
                String stats = context.Network.GetPathStats(p);
                if (stats != null) {
                    Out.Write(stats);
                }
            } catch (NetworkAdminException e) {
                Out.Write("Error retrieving stats: " + e.Message);
            }

            Out.WriteLine();
            Out.WriteLine();
        }
예제 #13
0
        private void AddPathToNetwork(string pathName, string pathType, IServiceAddress rootLeader,
		                              IServiceAddress[] rootServers)
        {
            if (pathType.Contains("|"))
                throw new ArgumentException("Invalid path type string", "pathType");
            if (pathName.Contains("|"))
                throw new ArgumentException("Invalid path name string", "pathName");

            string key = "path.info." + pathName;
            // Check the map doesn't already exist
            if (managerDb.GetValue(key) != null)
                throw new ApplicationException("Path already assigned");

            // Set the first path info version for this path name
            PathInfo mpathInfo = new PathInfo(pathName, pathType, 1, rootLeader, rootServers);

            // Add the path to the manager db cluster.
            managerDb.SetValue(key, mpathInfo.ToString());
        }
예제 #14
0
        private DataAddress InternalGetPathNow(PathInfo pathInfo, IServiceAddress rootServer)
        {
            MessageStream outputStream = new MessageStream();
            outputStream.AddMessage(new Message("getPathNow", pathInfo.PathName, pathInfo.VersionNumber));

            Message m = ProcessSingleRoot(outputStream, rootServer);
            if (m.HasError)
                throw new ApplicationException(m.ErrorMessage);

            return (DataAddress) m.Arguments[0].Value;
        }
예제 #15
0
        private void NotifyAllRootServersOfPost(PathInfo pathInfo, long uid, DataAddress rootNode)
        {
            // The root servers for the path,
            IServiceAddress[] roots = pathInfo.RootServers;

            // Create the message,
            MessageStream outputStream = new MessageStream();
            outputStream.AddMessage(new Message("notifyNewProposal", pathInfo.PathName, uid, rootNode));

            for (int i = 0; i < roots.Length; ++i) {
                IServiceAddress machine = roots[i];
                // Don't notify this service,
                if (!machine.Equals(address)) {
                    // If the service is up in the tracker,
                    if (serviceTracker.IsServiceUp(machine, ServiceType.Root)) {
                        // Send the message to the service,
                        IMessageProcessor processor = connector.Connect(machine, ServiceType.Root);
                        IEnumerable<Message> inputStream = processor.Process(outputStream);
                        // If return is a connection fault,
                        foreach (Message m in inputStream) {
                            if (m.HasError &&
                                ReplicatedValueStore.IsConnectionFault(m)) {
                                serviceTracker.ReportServiceDownClientReport(machine, ServiceType.Root);
                            }
                        }
                    }
                }
            }
        }
예제 #16
0
        private DataAddress[] GetHistoricalPathRoots(PathInfo pathInfo, long timeStart, long timeEnd)
        {
            // Fetch the path access object for the given name.
            PathAccess pathFile = GetPathAccess(pathInfo.PathName);

            // Returns the roots
            return pathFile.GetHistoricalPathRoots(timeStart, timeEnd);
        }
예제 #17
0
        private DataAddress PerformCommit(PathInfo pathInfo, DataAddress proposal)
        {
            IServiceAddress[] manSrvs = managerServers;

            // Fetch the path access object for the given name.
            PathAccess pathFile = GetPathAccess(pathInfo.PathName);

            IPath pathFunction;
            try {
                pathFunction = pathFile.Path;
            } catch (TypeLoadException e) {
                throw new CommitFaultException(String.Format("Type not found: {0}", e.Message));
            } catch (TypeInitializationException e) {
                throw new CommitFaultException(String.Format("Type instantiation exception: {0}", e.Message));
            } catch (AccessViolationException e) {
                throw new CommitFaultException(String.Format("Illegal Access exception: {0}", e.Message));
            }

            // Create the connection object (should be fairly lightweight)
            INetworkCache localNetCache = MachineState.GetCacheForManager(manSrvs);
            IPathConnection connection = new PathConnection(this, pathInfo, connector, manSrvs, localNetCache, serviceTracker);

            // Perform the commit,
            return pathFunction.Commit(connection, proposal);
        }
예제 #18
0
        private DataAddress GetPathLast(PathInfo pathInfo)
        {
            // Fetch the path access object for the given name.
            PathAccess pathFile = GetPathAccess(pathInfo.PathName);

            // Returns the last entry
            return pathFile.GetPathLast();
        }
예제 #19
0
 protected void AddPathToQueue(PathInfo pathInfo)
 {
     loadPathInfoQueue.Add(pathInfo);
 }
예제 #20
0
        public String GetPathStats(PathInfo pathInfo)
        {
            InspectNetwork();

            IServiceAddress rootLeader = pathInfo.RootLeader;

            // Check machine is in the schema,
            MachineProfile machineP = CheckMachineInNetwork(rootLeader);
            // Check it's root,
            if (!machineP.IsRoot)
                throw new NetworkAdminException("Machine '" + rootLeader + "' is not a root");

            // Perform the command,
            Message message = new Message("getPathStats", pathInfo.PathName, pathInfo.VersionNumber);

            Message m = Command(rootLeader, ServiceType.Root, message.AsStream());
            if (m.HasError)
                throw new NetworkAdminException(m.ErrorMessage);

            // Return the stats string for this path
            return (String) m.Arguments[0].Value;
        }