示例#1
0
        private LatestVersion ReadVersion(int fileRegisterIndex, Helper.Semantics semantics)
        {
            Console.WriteLine("READ VERSION " + fileRegisterIndex);

            string       filename     = fileRegister.FilenameAt(fileRegisterIndex);
            FileVersion  original     = fileRegister.FileDataAt(fileRegisterIndex).Version;
            FileMetadata fileMetadata = fileRegister.FileMetadataAt(fileRegisterIndex);
            // data server id / file data
            ConcurrentDictionary <string, FileVersion> reads = new ConcurrentDictionary <string, FileVersion>();
            int           requests      = 0;
            LatestVersion quorumVersion = null;


            //QUORUM
            while (true)
            {
                // voting
                ReadQuorum quorum = new ReadQuorum(fileMetadata.ReadQuorum, semantics);
                foreach (var entry in reads)
                {
                    FileVersion vote         = entry.Value;
                    string      dataServerId = entry.Key;

                    quorum.AddVote(vote, dataServerId);
                    if (quorum.CheckQuorum(vote, original))
                    {
                        quorumVersion = new LatestVersion(vote, quorum.DataServersIds(vote));
                        break;
                    }
                }

                // found the quorum file
                if (quorumVersion != null)
                {
                    break;
                }

                // if there are still pending requests
                // dont create new ones
                if (requests > 0)
                {
                    continue;
                }

                // if all the votes arrived at the quorum
                // stops when all requests are counted (requests = 0)
                if (quorum.Count == (requests + quorum.Count))
                {
                    // get possible new fileMetadata locations
                    // possible optimization
                    // check if there are no data servers
                    fileMetadata = OpenFileMetadata(filename);

                    // broadcast to all dataServers that have that file
                    foreach (var entry in fileMetadata.Locations)
                    {
                        string id            = entry.Key;
                        string location      = entry.Value;
                        string localFilename = fileMetadata.LocalFilenames[id];

                        // increment right away so it doesn't request untill its decremented
                        Interlocked.Increment(ref requests);
                        Thread request = new Thread(() =>
                        {
                            IDataServerToClient dataServer = (IDataServerToClient)Activator.GetObject(
                                typeof(IDataServerToClient),
                                location);
                            FileVersion fileVersion = null;
                            try
                            {
                                fileVersion = dataServer.Version(localFilename);
                            }
                            catch (ProcessFailedException) { }
                            catch (ProcessFreezedException) { }
                            finally
                            {
                                reads[id] = fileVersion;
                                Interlocked.Decrement(ref requests);
                            }
                        });
                        request.Start();
                    }
                }
            }

            return(quorumVersion);
        }
示例#2
0
文件: Client.cs 项目: jfloff/PADI
        private LatestVersion ReadVersion(int fileRegisterIndex, Helper.Semantics semantics)
        {
            Console.WriteLine("READ VERSION " + fileRegisterIndex);

            string filename = fileRegister.FilenameAt(fileRegisterIndex);
            FileVersion original = fileRegister.FileDataAt(fileRegisterIndex).Version;
            FileMetadata fileMetadata = fileRegister.FileMetadataAt(fileRegisterIndex);
            // data server id / file data
            ConcurrentDictionary<string, FileVersion> reads = new ConcurrentDictionary<string, FileVersion>();
            int requests = 0;
            LatestVersion quorumVersion = null;

            //QUORUM
            while (true)
            {
                // voting
                ReadQuorum quorum = new ReadQuorum(fileMetadata.ReadQuorum, semantics);
                foreach (var entry in reads)
                {
                    FileVersion vote = entry.Value;
                    string dataServerId = entry.Key;

                    quorum.AddVote(vote, dataServerId);
                    if (quorum.CheckQuorum(vote, original))
                    {
                        quorumVersion = new LatestVersion(vote, quorum.DataServersIds(vote));
                        break;
                    }
                }

                // found the quorum file
                if (quorumVersion != null) break;

                // if there are still pending requests
                // dont create new ones
                if (requests > 0) continue;

                // if all the votes arrived at the quorum
                // stops when all requests are counted (requests = 0)
                if (quorum.Count == (requests + quorum.Count))
                {
                    // get possible new fileMetadata locations
                    // possible optimization
                    // check if there are no data servers
                    fileMetadata = OpenFileMetadata(filename);

                    // broadcast to all dataServers that have that file
                    foreach (var entry in fileMetadata.Locations)
                    {
                        string id = entry.Key;
                        string location = entry.Value;
                        string localFilename = fileMetadata.LocalFilenames[id];

                        // increment right away so it doesn't request untill its decremented
                        Interlocked.Increment(ref requests);
                        Thread request = new Thread(() =>
                        {
                            IDataServerToClient dataServer = (IDataServerToClient)Activator.GetObject(
                                typeof(IDataServerToClient),
                                location);
                            FileVersion fileVersion = null;
                            try
                            {
                                fileVersion = dataServer.Version(localFilename);
                            }
                            catch (ProcessFailedException) { }
                            catch (ProcessFreezedException) { }
                            finally
                            {
                                reads[id] = fileVersion;
                                Interlocked.Decrement(ref requests);
                            }
                        });
                        request.Start();
                    }
                }
            }

            return quorumVersion;
        }