private void WaitForAndProcessProgress() { ProgressRecord progressRecord = null; bool flag = true; while (flag) { this.progressAvailable.WaitOne(); Tracer.TraceInformation("ProgressController.WaitForAndProcessProgress: Progress signaled.", new object[0]); flag = this.progressQueue.TryDequeue(out progressRecord); if (progressRecord != null) { try { if (progressRecord.RootExportedRecord != null) { this.target.ExportContext.WriteResultManifest(new ExportRecord[] { progressRecord.RootExportedRecord }); } else if (progressRecord.SourceErrorRecord != null) { this.target.ExportContext.WriteErrorLog(new ErrorRecord[] { progressRecord.SourceErrorRecord }); } else { if (progressRecord.ItemExportedRecords != null && progressRecord.ItemExportedRecords.Count > 0) { this.target.ExportContext.WriteResultManifest(progressRecord.ItemExportedRecords); } if (progressRecord.ItemErrorRecords != null && progressRecord.ItemErrorRecords.Count > 0) { this.target.ExportContext.WriteErrorLog(progressRecord.ItemErrorRecords); foreach (ErrorRecord errorRecord in progressRecord.ItemErrorRecords) { this.SearchResults.IncrementErrorItemCount(errorRecord.Item.SourceId); } } this.ReportStatistics(new ExportStatusEventArgs { ActualBytes = progressRecord.Size, ActualCount = progressRecord.ItemExportedRecords.Count + progressRecord.ItemErrorRecords.Count, ActualMailboxesProcessed = 0, ActualMailboxesTotal = 0, TotalDuration = progressRecord.Duration }); progressRecord.DataContext.ProcessedItemCount += progressRecord.ItemExportedRecords.Count + progressRecord.ItemErrorRecords.Count; this.StatusManager.Checkpoint(progressRecord.DataContext.SourceId); } } catch (Exception ex) { Tracer.TraceError("ProgressController.WaitForAndProcessProgress: Progress reporting thread error: {0}", new object[] { ex }); this.Stop(); throw; } } } }
public void WriteDataBatch(List <ItemInformation> dataBatch) { Tracer.TraceInformation("PstWriter.WriteDataBatch: Writing data batch for mailbox '{0}', item count: {1}", new object[] { this.dataContext.SourceId, dataBatch.Count }); ProgressRecord progressRecord = new ProgressRecord(this.dataContext); PSTSession pstsession = this.dataContext.IsPublicFolder ? this.pstPFSession : this.pstSession; try { foreach (ItemInformation itemInformation in dataBatch) { if (this.progressController.IsStopRequested) { Tracer.TraceInformation("PstWriter.WriteDataBatch: Stop requested when processing mailbox '{0}'", new object[] { this.dataContext.SourceId }); break; } try { if (this.dataContext.IsPublicFolder) { if (this.dataContext.IsUnsearchable) { if (this.unsearchablePFTotalSize > 0L && this.unsearchablePFTotalSize + (long)((ulong)itemInformation.Id.Size) > ConstantProvider.PSTSizeLimitInBytes) { this.ReOpenPFDataContext(); pstsession = this.pstPFSession; this.unsearchablePFTotalSize = 0L; } this.unsearchablePFTotalSize += (long)((ulong)itemInformation.Id.Size); } else { if (this.searchablePFTotalSize > 0L && this.searchablePFTotalSize + (long)((ulong)itemInformation.Id.Size) > ConstantProvider.PSTSizeLimitInBytes) { this.ReOpenPFDataContext(); pstsession = this.pstPFSession; this.searchablePFTotalSize = 0L; } this.searchablePFTotalSize += (long)((ulong)itemInformation.Id.Size); } } else if (this.dataContext.IsUnsearchable) { if (this.unsearchableMBTotalSize > 0L && this.unsearchableMBTotalSize + (long)((ulong)itemInformation.Id.Size) > ConstantProvider.PSTSizeLimitInBytes) { this.ReOpenMBDataContext(); pstsession = this.pstSession; this.unsearchableMBTotalSize = 0L; } this.unsearchableMBTotalSize += (long)((ulong)itemInformation.Id.Size); } else { if (this.searchableMBTotalSize > 0L && this.searchableMBTotalSize + (long)((ulong)itemInformation.Id.Size) > ConstantProvider.PSTSizeLimitInBytes) { this.ReOpenMBDataContext(); pstsession = this.pstSession; this.searchableMBTotalSize = 0L; } this.searchableMBTotalSize += (long)((ulong)itemInformation.Id.Size); } if (itemInformation.Error == null) { if (itemInformation.Id.IsDuplicate) { progressRecord.ReportItemExported(itemInformation.Id, null, null); } else { IFolder parentFolder = this.targetFolderProvider.GetParentFolder(pstsession, itemInformation.Id.ParentFolder, this.target.ExportContext.ExportMetadata.IncludeDuplicates); if (parentFolder == null) { if (!this.dataContext.IsPublicFolder) { progressRecord.ReportItemError(itemInformation.Id, this.currentRootRecord, ExportErrorType.ParentFolderNotFound, string.Format(CultureInfo.CurrentCulture, "Parent folder '{0}' is missing, this may caused by newly created folder", new object[] { itemInformation.Id.ParentFolder })); Tracer.TraceError("PstWriter.WriteDataBatch: Failed to get the parent folder of current message to export. Mailbox: '{0}', Message Id: '{1}', Folder Path: '{2}'", new object[] { this.dataContext.SourceId, itemInformation.Id.Id, itemInformation.Id.ParentFolder }); } else { progressRecord.ReportItemError(itemInformation.Id, this.currentPFRecord, ExportErrorType.ParentFolderNotFound, string.Format(CultureInfo.CurrentCulture, "Parent folder '{0}' is missing, this may caused by newly created folder", new object[] { itemInformation.Id.ParentFolder })); Tracer.TraceError("PstWriter.WriteDataBatch: Failed to get the parent folder of current message to export. Mailbox: '{0}', Message Id: '{1}', Folder Path: '{2}'", new object[] { this.dataContext.SourceId, itemInformation.Id.Id, itemInformation.Id.ParentFolder }); } } else { IMessage message = PstWriter.CreatePstMessage(pstsession, parentFolder, itemInformation, !this.target.ExportContext.ExportMetadata.IncludeDuplicates); if (!this.dataContext.IsPublicFolder) { progressRecord.ReportItemExported(itemInformation.Id, this.currentRootRecord.ExportFile.Name + '/' + PstWriter.CreateEntryIdFromNodeId(pstsession.MessageStore.Guid, message.Id), this.currentRootRecord); } else { progressRecord.ReportItemExported(itemInformation.Id, this.currentPFRecord.ExportFile.Name + '/' + PstWriter.CreateEntryIdFromNodeId(pstsession.MessageStore.Guid, message.Id), this.currentPFRecord); } } } } else if (!this.dataContext.IsPublicFolder) { progressRecord.ReportItemError(itemInformation.Id, this.currentRootRecord, itemInformation.Error.ErrorType, itemInformation.Error.Message); } else { progressRecord.ReportItemError(itemInformation.Id, this.currentPFRecord, itemInformation.Error.ErrorType, itemInformation.Error.Message); } } catch (ExportException ex) { Tracer.TraceError("PstWriter.WriteDataBatch: Exception happed. Mailbox:'{0}'. Exception:'{1}'", new object[] { this.dataContext.SourceId, ex }); if (!this.dataContext.IsPublicFolder) { progressRecord.ReportItemError(itemInformation.Id, this.currentRootRecord, ex.ErrorType, ex.Message); } else { progressRecord.ReportItemError(itemInformation.Id, this.currentPFRecord, ex.ErrorType, ex.Message); } } } } finally { this.timer.Stop(); progressRecord.ReportDuration(this.timer.Elapsed); this.progressController.ReportProgress(progressRecord); this.timer.Restart(); } }
private void InternalExport() { using (IContextualBatchDataWriter <List <ItemInformation> > contextualBatchDataWriter = this.target.CreateDataWriter(this)) { bool errorHappened = false; try { if (this.StatusManager.AllSourceInformation != null) { ScenarioData.Current["M"] = this.StatusManager.AllSourceInformation.Count.ToString(); } this.sourceDataProviderManager.CreateSourceServiceClients(this.StatusManager.AllSourceInformation); this.ItemListGenerator.AllSourceInformation = this.StatusManager.AllSourceInformation; int num = 0; this.ReportStatistics(new ExportStatusEventArgs { ActualBytes = 0L, ActualCount = 0, ActualMailboxesProcessed = 0, ActualMailboxesTotal = this.StatusManager.AllSourceInformation.Count, TotalDuration = TimeSpan.Zero }); foreach (SourceInformation sourceInformation in this.StatusManager.AllSourceInformation.Values) { if (sourceInformation.Configuration != null && sourceInformation.Configuration.SourceFilter != null) { ScenarioData.Current["QL"] = sourceInformation.Configuration.SourceFilter.Length.ToString(); } Tracer.TraceInformation("ProgressController.InternalExport: Exporting source '{0}'. ItemCount: {1}; ProcessedItemCount: {2}; UnsearchableItemCount: {3}; ProcessedUnsearchableItemCount: {4}; DuplicateItemCount: {5}; UnsearchableDuplicateItemCount: {6}; ErrorItemCount: {7}", new object[] { sourceInformation.Configuration.Id, sourceInformation.Status.ItemCount, sourceInformation.Status.ProcessedItemCount, sourceInformation.Status.UnsearchableItemCount, sourceInformation.Status.ProcessedUnsearchableItemCount, sourceInformation.Status.DuplicateItemCount, sourceInformation.Status.UnsearchableDuplicateItemCount, sourceInformation.Status.ErrorItemCount }); if (this.IsStopRequested) { Tracer.TraceInformation("ProgressController.InternalExport: Stop requested.", new object[0]); this.StatusManager.BeginProcedure(ProcedureType.Stop); break; } try { num++; this.ExportSourceMailbox(contextualBatchDataWriter, sourceInformation, false); this.ExportSourceMailbox(contextualBatchDataWriter, sourceInformation, true); if (sourceInformation.Configuration.Id.StartsWith("\\")) { errorHappened = true; } Tracer.TraceInformation("ProgressController.InternalExport: Exporting source '{0}'. ItemCount: {1}; ProcessedItemCount: {2}; UnsearchableItemCount: {3}; ProcessedUnsearchableItemCount: {4}; DuplicateItemCount: {5}; UnsearchableDuplicateItemCount: {6}; ErrorItemCount: {7}", new object[] { sourceInformation.Configuration.Id, sourceInformation.Status.ItemCount, sourceInformation.Status.ProcessedItemCount, sourceInformation.Status.UnsearchableItemCount, sourceInformation.Status.ProcessedUnsearchableItemCount, sourceInformation.Status.DuplicateItemCount, sourceInformation.Status.UnsearchableDuplicateItemCount, sourceInformation.Status.ErrorItemCount }); } catch (ExportException ex) { if (ex.ErrorType == ExportErrorType.TargetOutOfSpace) { Tracer.TraceInformation("ProgressController.InternalExport: Target level error occurs during export.: {0}", new object[] { ex }); throw; } Tracer.TraceInformation("ProgressController.InternalExport: Source level error occurs during export: {0}", new object[] { ex }); ProgressRecord progressRecord = new ProgressRecord(); progressRecord.ReportSourceError(new ErrorRecord { Item = null, ErrorType = ex.ErrorType, DiagnosticMessage = ex.Message, SourceId = sourceInformation.Configuration.Id, Time = DateTime.UtcNow }); this.ReportProgress(progressRecord); } finally { this.ReportStatistics(new ExportStatusEventArgs { ActualBytes = 0L, ActualCount = 0, ActualMailboxesProcessed = num, ActualMailboxesTotal = this.StatusManager.AllSourceInformation.Count, TotalDuration = TimeSpan.Zero }); } } errorHappened = true; } finally { contextualBatchDataWriter.ExitPFDataContext(errorHappened); } } }