public void Pop(Server server) { System.Diagnostics.Debug.Assert(_logLength > 0); var lastIndex = _logIndices[--_logLength]; //roll back add if (lastIndex.Type == LogIndexType.AddServer) { System.Diagnostics.Debug.Assert(_configLocked); var id = GetIPEndPoint(GetData(lastIndex)); _configLocked = false; if (!server.ID.Equals(id)) server.RemoveClientFromLog(id); Console.WriteLine("{0}x: Rolling back add server {1} and unlocking config", server.Name, id); saveSuperBlock(); } else if (lastIndex.Type == LogIndexType.RemoveServer) { System.Diagnostics.Debug.Assert(_configLocked); var id = GetIPEndPoint(GetData(lastIndex)); _configLocked = false; if (!server.ID.Equals(id)) server.AddClientFromLog(id); Console.WriteLine("{0}x: Rolling back remove server {1} and unlocking config", server.Name, id); saveSuperBlock(); } //_logLength--; }
//public bool WriteChunk(Server server, byte[] ) public bool Push(Server server, LogEntry data) { //we couldn't take this entry because we are still waiting for another //to finish if (_configLocked) { return false; } //if (data.Data == null && data.Index.ChunkSize > 0) //{ // Console.WriteLine("{0}: Data length is 0 and data chunksize is {1}", server.Name, data.Index.ChunkSize); // return false; //} //if (data.Data != null && data.Data.Length != data.Index.ChunkSize) //{ // Console.WriteLine("{0}: Data length is {1} and data chunksize is {2}", server.Name, data.Data.Length, data.Index.ChunkSize); // return false; //} // we must first write the data to the dat file // in case of crash in between log data and log entry // this will orphan the data and on startup will reclaim the space // stream length is in UNSIGN but seek is SIGN? // seek before we commit the data so we are at the right position _logIndexWriter.Seek((int)(SUPER_BLOCK_SIZE + _logLength * LogIndex.LOG_RECORD_SIZE), SeekOrigin.Begin); // make sure we have enough capacity ensureLogIndices(_logLength + 1); //write to log data file _logDataFile.Seek(DataPosition, SeekOrigin.Begin); _logDataFile.Write(data.Data, 0, (int)data.Index.ChunkSize); //update log entries _logIndices[_logLength] = data.Index; //flush data _logDataFile.Flush(); //write data _logIndexWriter.Write(data.Index.Term); _logIndexWriter.Write((uint)data.Index.Type); _logIndexWriter.Write(data.Index.ChunkOffset); _logIndexWriter.Write(data.Index.ChunkSize); _logIndexWriter.Write(data.Index.Flag1); _logIndexWriter.Write(data.Index.Flag2); _logIndexWriter.Write(data.Index.Flag3); _logIndexWriter.Write(data.Index.Flag4); _logIndexWriter.Flush(); //inc log index _logLength++; //add server before commit if (data.Index.Type == LogIndexType.AddServer) { var id = GetIPEndPoint(data.Data); if (!server.ID.Equals(id)) server.AddClientFromLog(id); //System.Diagnostics.Debug.Assert(_configLocked == false); Console.WriteLine("{0}: Adding server {1} and locking config", server.Name, id); _configLocked = true; saveSuperBlock(); } else if (data.Index.Type == LogIndexType.RemoveServer) { var id = GetIPEndPoint(data.Data); if (!server.ID.Equals(id)) server.RemoveClientFromLog(id); //System.Diagnostics.Debug.Assert(_configLocked == false); Console.WriteLine("{0}: Removing server {1} and locking config", server.Name, id); _configLocked = true; saveSuperBlock(); } //this can happen on log rollbacks //System.Diagnostics.Debug.Assert(_logDataFile.Length == DataPosition); return true; }