internal override void Run() { int collectionItterated = 1; LoggerManager.Instance.SetThreadContext(new LoggerContext() { ShardName = _context.LocalShardName != null ? _context.LocalShardName : "", DatabaseName = Database != null ? Database : "" }); try { IDatabaseStore dbInstance = _context.DatabasesManager.GetDatabase(Database); foreach (string _collection in Collections) { if (((Storage.DatabaseStore)dbInstance).Collections.ContainsKey(_collection)) { //Add custom object Query defaultQuery = new Query(); defaultQuery.QueryText = "Select * from "; //M_Note: precausion used incase user goes bonkers whilst naming his collections if (_collection.Contains("\"")) { defaultQuery.QueryText += "$" + _collection + "$"; } else { defaultQuery.QueryText += "\"" + _collection + "\""; } ReadQueryOperation readQueryOperation = new ReadQueryOperation(); readQueryOperation.Database = Database.ToString(); readQueryOperation.Collection = _collection; readQueryOperation.Query = defaultQuery; ArrayList docList = new ArrayList(); long currentSize = 0; DataSlice _activeSlice = PersistenceManager.ActiveContext.GetBackupFile(Database).CreateNewDataSlice(); _activeSlice.SliceHeader.Collection = _collection; _activeSlice.SliceHeader.Database = Database; _activeSlice.SliceHeader.Cluster = Cluster; _activeSlice.SliceHeader.ContentType = DataSliceType.Data; try { ReadQueryResponse readQueryResponse = (ReadQueryResponse)dbInstance.ExecuteReader(readQueryOperation); if (readQueryResponse.IsSuccessfull) { _dbReader = new CollectionReader((DataChunk)readQueryResponse.DataChunk, _context.TopologyImpl, Database, _collection); //create data slice to be written in the common queue while (_dbReader != null && _dbReader.ReadNext() && _dbReader.GetDocument() != null) { //get document and create chunk and add to shared storage IJSONDocument _doc = _dbReader.GetDocument(); // verify size if (currentSize + _doc.Size <= _activeSlice.Capcity) { docList.Add(_doc); currentSize += _doc.Size + 2;// Hack to accomodate the 2 bytes serialization is going add } else { DataSlice _nxtSlice = PersistenceManager.ActiveContext.GetBackupFile(Database).CreateNewDataSlice(); _nxtSlice.SliceHeader.Collection = _collection; _nxtSlice.SliceHeader.Database = Database; _nxtSlice.SliceHeader.Cluster = Cluster; _nxtSlice.SliceHeader.ContentType = DataSliceType.Data; _activeSlice.Data = CompactBinaryFormatter.ToByteBuffer(docList, string.Empty); _activeSlice.SliceHeader.DataCount = docList.Count; _activeSlice.SliceHeader.TotalSize = _activeSlice.Data.LongLength; // Add to shared queue PersistenceManager.SharedQueue.Add(_activeSlice); _activeSlice = _nxtSlice; docList.Clear(); docList.Add(_doc); currentSize = 0; currentSize += _doc.Size; } } _dbReader.Dispose(); // write final data set if (docList.Count > 0) { _activeSlice.Data = CompactBinaryFormatter.ToByteBuffer(docList, string.Empty); _activeSlice.SliceHeader.DataCount = docList.Count; _activeSlice.SliceHeader.TotalSize = _activeSlice.Data.LongLength; // Add to shared queue PersistenceManager.SharedQueue.Add(_activeSlice); docList.Clear(); } // submit status ExecutionStatus.Status = RecoveryStatus.Executing; ExecutionStatus.PercentageExecution = (collectionItterated / Collections.Count);//[M_NOTE] rudementary logic, change this ExecutionStatus.MessageTime = DateTime.Now; ExecutionStatus.Message = "Completed Backup of " + Database + "_" + _collection + " : " + _collection; collectionItterated++; if (ProgressHandler != null) { ProgressHandler.SubmitRecoveryState(ExecutionStatus); } } else { throw new Exception("Operation failed Error code: " + readQueryResponse.ErrorCode); } } catch (Exception ex) { if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("DatabaseBackupJob.Run()", Database + " : " + ex.ToString()); } collectionItterated--; } } } // Add command slice DataSlice finalSlice = new DataSlice(999999); finalSlice.SliceHeader.Collection = "Complete"; finalSlice.SliceHeader.Database = Database; finalSlice.SliceHeader.Cluster = Cluster; finalSlice.SliceHeader.ContentType = DataSliceType.Command; finalSlice.Data = CompactBinaryFormatter.ToByteBuffer("Data_Complete_Adding", string.Empty); PersistenceManager.SharedQueue.Add(finalSlice); while (!PersistenceManager.SharedQueue.Consumed) { // wait till all data has been consumed and written //M_TODO: // Add timeout interval for file writing, incase the data is not being consumed and timeout span has been reached, break the loop and DIE!!! } if (PersistenceManager.SharedQueue.Consumed) { // submit status ExecutionStatus.Status = RecoveryStatus.Completed; ExecutionStatus.PercentageExecution = 1;//[M_NOTE] rudementary logic, change this ExecutionStatus.MessageTime = DateTime.Now; ExecutionStatus.Message = "Completed Backup of " + Database; } else { // submit status ExecutionStatus.Status = RecoveryStatus.Failure; ExecutionStatus.PercentageExecution = (collectionItterated / Collections.Count);//[M_NOTE] rudementary logic, change this ExecutionStatus.MessageTime = DateTime.Now; ExecutionStatus.Message = "Failed Backup of " + Database; } if (ProgressHandler != null) { System.Threading.Tasks.Task.Factory.StartNew(() => ProgressHandler.SubmitRecoveryState(ExecutionStatus)); } if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsInfoEnabled) { LoggerManager.Instance.RecoveryLogger.Info("DatabaseBackupJob.Run()", Database + "Completed"); } } catch (ThreadAbortException) { if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsDebugEnabled) { LoggerManager.Instance.RecoveryLogger.Debug("DatabaseBackupJob.Run()", "Thread stopped"); } Thread.ResetAbort(); } catch (Exception exp) { if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("DatabaseBackupJob.Run()", Database + " : " + exp.ToString()); } ExecutionStatus.Status = RecoveryStatus.Failure; ExecutionStatus.PercentageExecution = (collectionItterated / Collections.Count);//[M_NOTE] rudementary logic, change this ExecutionStatus.MessageTime = DateTime.Now; ExecutionStatus.Message = "Failed Backup of " + Database; if (ProgressHandler != null) { System.Threading.Tasks.Task.Factory.StartNew(() => ProgressHandler.SubmitRecoveryState(ExecutionStatus)); } } }