예제 #1
0
        public void Write(int fileRegisterIndex, byte[] contents)
        {
            Console.WriteLine("WRITE FILE = " + fileRegisterIndex);

            try
            {
                // forces to get always the most recent file
                FileVersion latest = ReadVersion(fileRegisterIndex, Helper.Semantics.MONOTONIC).Version;
                latest.Increment(Client.id);
                FileData fileData = new FileData(latest, contents);

                string       filename     = fileRegister.FilenameAt(fileRegisterIndex);
                FileMetadata fileMetadata = fileRegister.FileMetadataAt(fileRegisterIndex);
                // data server id / bool write
                ConcurrentDictionary <string, bool> writes = new ConcurrentDictionary <string, bool>();
                int  requests      = 0;
                bool quorumReached = false;

                //QUORUM
                while (true)
                {
                    // voting
                    WriteQuorum quorum = new WriteQuorum(fileMetadata.WriteQuorum);
                    foreach (var entry in writes)
                    {
                        bool vote = entry.Value;

                        quorum.AddVote(vote);
                        if (quorum.CheckQuorum())
                        {
                            quorumReached = true;
                            break;
                        }
                    }

                    // found the quorum file
                    if (quorumReached)
                    {
                        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 dataa 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);
                                bool vote = false;
                                try
                                {
                                    dataServer.Write(localFilename, fileData);
                                    vote = true;
                                }
                                catch (ProcessFailedException) { }
                                catch (ProcessFreezedException) { }
                                finally
                                {
                                    writes[id] = vote;
                                    Interlocked.Decrement(ref requests);
                                }
                            });
                            request.Start();
                        }
                    }
                }

                // update file registers
                fileRegister.SetFileDataAt(fileRegisterIndex, fileData);
            }
            catch (FileDoesNotExistException e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }
예제 #2
0
파일: Client.cs 프로젝트: jfloff/PADI
        public void Write(int fileRegisterIndex, byte[] contents)
        {
            Console.WriteLine("WRITE FILE = " + fileRegisterIndex);

            try
            {
                // forces to get always the most recent file
                FileVersion latest = ReadVersion(fileRegisterIndex, Helper.Semantics.MONOTONIC).Version;
                latest.Increment(Client.id);
                FileData fileData = new FileData(latest, contents);

                string filename = fileRegister.FilenameAt(fileRegisterIndex);
                FileMetadata fileMetadata = fileRegister.FileMetadataAt(fileRegisterIndex);
                // data server id / bool write
                ConcurrentDictionary<string, bool> writes = new ConcurrentDictionary<string, bool>();
                int requests = 0;
                bool quorumReached = false;

                //QUORUM
                while (true)
                {
                    // voting
                    WriteQuorum quorum = new WriteQuorum(fileMetadata.WriteQuorum);
                    foreach (var entry in writes)
                    {
                        bool vote = entry.Value;

                        quorum.AddVote(vote);
                        if (quorum.CheckQuorum())
                        {
                            quorumReached = true;
                            break;
                        }
                    }

                    // found the quorum file
                    if (quorumReached) 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 dataa 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);
                                bool vote = false;
                                try
                                {
                                    dataServer.Write(localFilename, fileData);
                                    vote = true;
                                }
                                catch (ProcessFailedException) { }
                                catch (ProcessFreezedException) { }
                                finally
                                {
                                    writes[id] = vote;
                                    Interlocked.Decrement(ref requests);
                                }
                            });
                            request.Start();
                        }
                    }
                }

                // update file registers
                fileRegister.SetFileDataAt(fileRegisterIndex, fileData);
            }
            catch (FileDoesNotExistException e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }