Esempio n. 1
0
        private FileData ReadFileData(int fileRegisterIndex, Helper.Semantics semantics)
        {
            // gets latest version
            LatestVersion latestVersion = ReadVersion(fileRegisterIndex, semantics);

            // requests file data to dataServer with latest version
            List <string> dataServersIds = latestVersion.DataServerIds;

            // loops until  we get something from a read from any dataServer
            while (true)
            {
                foreach (string id in dataServersIds)
                {
                    string location      = fileRegister.FileMetadataAt(fileRegisterIndex).Locations[id];
                    string localFilename = fileRegister.FileMetadataAt(fileRegisterIndex).LocalFilenames[id];

                    IDataServerToClient dataServer = (IDataServerToClient)Activator.GetObject(
                        typeof(IDataServerToClient),
                        location);

                    try
                    {
                        FileData fileData = dataServer.Read(localFilename);

                        // update file registers
                        fileRegister.SetFileDataAt(fileRegisterIndex, fileData);
                        return(fileData);
                    }
                    catch (ProcessFailedException) { }
                    catch (ProcessFreezedException) { }
                }
            }
        }
Esempio n. 2
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;
            }
        }
Esempio n. 3
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);
        }