Пример #1
0
        public void write(int fileRegister, int regPosition)
        {
            //Write variables restore
            _writeResponses = 0;
            _writeOperationSucedded = true;

            LogPrint("Write Operation");
            LogPrint("\tFile Register: " + fileRegister + " String Register: " + regPosition);

            if(_filesInfo[fileRegister] == null)
                throw new Exception("Ficheiro nao existe!");

            PADI_FS_Library.File fileToWrite = _filesInfo[fileRegister].Item2;
            String contentToWrite = _stringRegister[regPosition];

            //if the file register to write is null (that is, if that file does not exists in the client) then
            //the version number used to write will be 0, otherwise it will be the version number of the existing file plus one
            int versionNumberToWrite = 1;
            FileMetadata fileMetadataToWrite;
            if (fileToWrite != null) {
                versionNumberToWrite = fileToWrite.VersionNumber + 1;
            }
            fileMetadataToWrite = _filesInfo[fileRegister].Item1;

            //if data servers with this file is smaller than the write quorum do REOPEN
            while (_filesInfo[fileRegister].Item1.FileDataServersLocations.Count < _filesInfo[fileRegister].Item1.WriteQuorum)
            {
                FileMetadata fileMetadataToReopen = null;

                Tuple<string, MetadataServerInterface> aliveMetadataServerMaster = isAnyoneAlive();

                while (aliveMetadataServerMaster == null)
                    aliveMetadataServerMaster = isAnyoneAlive();

                //Someone (MetadataServer) is alive (no matter who - it wont be null)
                if (aliveMetadataServerMaster != null) //just to check xD
                {
                    MetadataServerInterface aliveMetadataServerMasterInterface = aliveMetadataServerMaster.Item2;

                    fileMetadataToReopen = aliveMetadataServerMasterInterface.open(_filesInfo[fileRegister].Item1.Filename);

                    _filesInfo[fileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(fileMetadataToReopen, _filesInfo[fileRegister].Item2);

                }
            }

            fileMetadataToWrite = _filesInfo[fileRegister].Item1;

            //Call every Data Server that contains the file
            foreach (Tuple<string, string> fileDataServerLocation in fileMetadataToWrite.FileDataServersLocations)
            {
                DataServerInterface dataServerProxy = (DataServerInterface)Activator.GetObject(
                                                        typeof(DataServerInterface),
                                                        fileDataServerLocation.Item1);

                // Alternative 2: asynchronous call with callback
                // Create delegate to remote method
                RemoteAsyncWriteFileDelegate RemoteDel = new RemoteAsyncWriteFileDelegate(dataServerProxy.write);
                // Create delegate to local callback
                AsyncCallback RemoteCallback = new AsyncCallback(this.WriteFileRemoteAsyncCallBack);
                // Call remote method
                IAsyncResult RemAr = RemoteDel.BeginInvoke(fileDataServerLocation.Item2, versionNumberToWrite, contentToWrite, RemoteCallback, null);
            }

            //Waits for a quorum of Write Responses
            while (_writeResponses < fileMetadataToWrite.WriteQuorum) //ESTA A HAVER PROBLEMAS AQUI ???
            {
                continue;
            }

            if (_writeOperationSucedded == false)
            {
                LogPrint("Not Sucessfull!");
                throw new FileDoesntExistException(_filesInfo[fileRegister].Item1.Filename);
            }

            //Updates local registers (not really necessary because before any write the client has to make a read)
            //Info: They arent updated if file didnt exist before
            if (fileToWrite == null)
            {
                PADI_FS_Library.File newFile = new PADI_FS_Library.File(fileMetadataToWrite.Filename, contentToWrite, versionNumberToWrite);
                _filesInfo[fileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(fileMetadataToWrite, newFile);
            }
            else
            {
                _filesInfo[fileRegister].Item2.VersionNumber = versionNumberToWrite;
                _filesInfo[fileRegister].Item2.FileContents = contentToWrite;
            }

            LogPrint("Sucessful!");

            return;
        }
Пример #2
0
        // Copy Operation
        public string copy(int sourceFileRegister, string semantics, int destinFileRegister, byte[] salt)
        {
            string saltString = System.Text.Encoding.Default.GetString(salt);
            LogPrint("Copy Operation");
            LogPrint("\t Source File Register: " + sourceFileRegister + " Destination File Register: " + destinFileRegister +
                " Semantics: " + semantics + " Salt: " + saltString);

            //Read variables restore
            _readResponses = 0;
            _readFilesResponses = new List<PADI_FS_Library.File>();

            // Variables for retry (monotonic)
            Boolean _success = false;
            int _retry = 3;

            FileMetadata fileMetadataToRead;
            string contentToWrite;
            PADI_FS_Library.File fileToSave = null;

            //if the file register to read is null (that is, if that file does not exists in the client) sends an exception
            if (_filesInfo[sourceFileRegister] != null)
            {
                fileMetadataToRead = _filesInfo[sourceFileRegister].Item1;
            }
            else throw new Exception("Registo na posicao " + sourceFileRegister + " nao existe");

            //if data servers with this file is smaller than the read quorum do REOPEN
            while (_filesInfo[sourceFileRegister].Item1.FileDataServersLocations.Count < _filesInfo[sourceFileRegister].Item1.ReadQuorum)
            {
                LogPrint("\t!!!REOPEN FILE!!!");

                FileMetadata fileMetadataToReopen = null;

                Tuple<string, MetadataServerInterface> aliveMetadataServerMaster = isAnyoneAlive();

                while (aliveMetadataServerMaster == null)
                    aliveMetadataServerMaster = isAnyoneAlive();

                //Someone (MetadataServer) is alive (no matter who - it wont be null)
                if (aliveMetadataServerMaster != null) //just to check xD
                {
                    MetadataServerInterface aliveMetadataServerMasterInterface = aliveMetadataServerMaster.Item2;

                    fileMetadataToReopen = aliveMetadataServerMasterInterface.open(_filesInfo[sourceFileRegister].Item1.Filename);

                    _filesInfo[sourceFileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(fileMetadataToReopen, _filesInfo[sourceFileRegister].Item2);

                }
            }

            fileMetadataToRead = _filesInfo[sourceFileRegister].Item1;

            while (_retry > 0)
            {
                //Call every Data Server that contains the file
                foreach (Tuple<string, string> fileDataServerLocation in fileMetadataToRead.FileDataServersLocations)
                {
                    DataServerInterface dataServerProxy = (DataServerInterface)Activator.GetObject(
                                                            typeof(DataServerInterface),
                                                            fileDataServerLocation.Item1);

                    // Alternative 2: asynchronous call with callback
                    // Create delegate to remote method
                    RemoteAsyncGetFileDelegate RemoteDel = new RemoteAsyncGetFileDelegate(dataServerProxy.read);
                    // Create delegate to local callback
                    AsyncCallback RemoteCallback = new AsyncCallback(this.GetFileRemoteAsyncCallBack);
                    // Call remote method
                    IAsyncResult RemAr = RemoteDel.BeginInvoke(fileDataServerLocation.Item2, semantics, RemoteCallback, null);
                }

                //Waits for a quorum of Read Responses
                while (_readResponses < fileMetadataToRead.ReadQuorum)
                {
                    continue;
                }

                //After getting a quorum decides what to save (the most recent version of the files obtained)
                int counter = 0;
                int version = -1;
                foreach (PADI_FS_Library.File fileRead in _readFilesResponses)
                {
                    if (counter == fileMetadataToRead.ReadQuorum)
                        break;

                    if (fileRead.VersionNumber >= version)
                    {
                        version = fileRead.VersionNumber;
                        fileToSave = fileRead;
                    }

                    counter++;
                }

                //fileToSave = null problem (maybe because someone deleted the file in the exact moment this client was going to read it, etc)
                if (fileToSave == null)
                {
                    LogPrint("Not Sucessfull!");
                    throw new FileDoesntExistException(_filesInfo[sourceFileRegister].Item1.Filename);
                }
                else
                {
                    //Array registers update - monotonic and default
                    if (semantics.Equals("monotonic"))
                    {
                        if (_filesInfo[sourceFileRegister].Item2 == null || fileToSave.VersionNumber >= _filesInfo[sourceFileRegister].Item2.VersionNumber)
                        {
                            _filesInfo[sourceFileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(_filesInfo[sourceFileRegister].Item1, fileToSave);
                            _success = true;
                            _retry = 0;
                        }
                        else _retry--;
                    }
                    else if (semantics.Equals("default"))
                    {
                        _filesInfo[sourceFileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(_filesInfo[sourceFileRegister].Item1, fileToSave);
                        _success = true;
                        _retry = 0;
                    }
                    else throw new Exception("Unknown Semantics");

                }
                if (!_success)
                    LogPrint("Version too old, retrying...");
            }
            if (!_success)
                return ("Unable to fetch a recent version. Aborting");

            contentToWrite = fileToSave.FileContents + saltString;

            //Write variables restore
            _writeResponses = 0;
            _writeOperationSucedded = true;

            PADI_FS_Library.File fileToWrite = _filesInfo[destinFileRegister].Item2;

            //if the file register to write is null (that is, if that file does not exists in the client) then
            //the version number used to write will be 0, otherwise it will be the version number of the existing file plus one
            int versionNumberToWrite = 1;
            FileMetadata fileMetadataToWrite;
            if (fileToWrite != null)
                versionNumberToWrite = fileToWrite.VersionNumber + 1;
            fileMetadataToWrite = _filesInfo[destinFileRegister].Item1;

            //if data servers with this file is smaller than the write quorum do REOPEN
            while (_filesInfo[destinFileRegister].Item1.FileDataServersLocations.Count < _filesInfo[destinFileRegister].Item1.WriteQuorum)
            {
                FileMetadata fileMetadataToReopen = null;

                Tuple<string, MetadataServerInterface> aliveMetadataServerMaster = isAnyoneAlive();

                while (aliveMetadataServerMaster == null)
                    aliveMetadataServerMaster = isAnyoneAlive();

                //Someone (MetadataServer) is alive (no matter who - it wont be null)
                if (aliveMetadataServerMaster != null) //just to check xD
                {
                    MetadataServerInterface aliveMetadataServerMasterInterface = aliveMetadataServerMaster.Item2;

                    fileMetadataToReopen = aliveMetadataServerMasterInterface.open(_filesInfo[destinFileRegister].Item1.Filename);

                    _filesInfo[destinFileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(fileMetadataToReopen, _filesInfo[destinFileRegister].Item2);

                }
            }

            fileMetadataToWrite = _filesInfo[destinFileRegister].Item1;

            //Call every Data Server that contains the file
            foreach (Tuple<string, string> fileDataServerLocation in fileMetadataToWrite.FileDataServersLocations)
            {
                DataServerInterface dataServerProxy = (DataServerInterface)Activator.GetObject(
                                                        typeof(DataServerInterface),
                                                        fileDataServerLocation.Item1);

                // Alternative 2: asynchronous call with callback
                // Create delegate to remote method
                RemoteAsyncWriteFileDelegate RemoteDel = new RemoteAsyncWriteFileDelegate(dataServerProxy.write);
                // Create delegate to local callback
                AsyncCallback RemoteCallback = new AsyncCallback(this.WriteFileRemoteAsyncCallBack);
                // Call remote method
                IAsyncResult RemAr = RemoteDel.BeginInvoke(fileDataServerLocation.Item2, versionNumberToWrite, contentToWrite, RemoteCallback, null);
            }

            //Waits for a quorum of Write Responses
            while (_writeResponses < fileMetadataToWrite.WriteQuorum) //ESTA A HAVER PROBLEMAS AQUI ???
            {
                continue;
            }

            if (_writeOperationSucedded == false)
            {
                LogPrint("Not Sucessfull!");
                throw new FileDoesntExistException(_filesInfo[destinFileRegister].Item1.Filename);
            }

            //Updates local registers (not really necessary because before any write the client has to make a read)
            //Info: They arent updated if file didnt exist before
            if (fileToWrite == null)
            {
                PADI_FS_Library.File newFile = new PADI_FS_Library.File(fileMetadataToWrite.Filename, contentToWrite, versionNumberToWrite);
                _filesInfo[destinFileRegister] = new Tuple<FileMetadata, PADI_FS_Library.File>(fileMetadataToWrite, newFile);
            }
            else
            {
                _filesInfo[destinFileRegister].Item2.VersionNumber = versionNumberToWrite;
                _filesInfo[destinFileRegister].Item2.FileContents = contentToWrite;
            }

            LogPrint("Sucessful!");

            return contentToWrite;
        }