public static Task Run(Snapshots.ISnapshotService snapshot, Options options, BackupDatabase database, long lastfilesetid, CancellationToken token) { return(AutomationExtensions.RunTask(new { Input = Backup.Channels.SourcePaths.ForRead, StreamBlockChannel = Channels.StreamBlock.ForWrite, Output = Backup.Channels.ProcessedFiles.ForWrite, }, async self => { var emptymetadata = Utility.WrapMetadata(new Dictionary <string, string>(), options); var prevprefix = new KeyValuePair <string, long>(null, -1); var CHECKFILETIMEONLY = options.CheckFiletimeOnly; var DISABLEFILETIMECHECK = options.DisableFiletimeCheck; while (true) { var path = await self.Input.ReadAsync(); var lastwrite = new DateTime(0, DateTimeKind.Utc); var attributes = default(FileAttributes); try { lastwrite = snapshot.GetLastWriteTimeUtc(path); } catch (Exception ex) { Logging.Log.WriteWarningMessage(FILELOGTAG, "TimestampReadFailed", ex, "Failed to read timestamp on \"{0}\"", path); } try { attributes = snapshot.GetAttributes(path); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(FILELOGTAG, "FailedAttributeRead", "Failed to read attributes from {0}: {1}", path, ex.Message); } // If we only have metadata, stop here if (await ProcessMetadata(path, attributes, lastwrite, options, snapshot, emptymetadata, database, self.StreamBlockChannel).ConfigureAwait(false)) { try { var split = Database.LocalDatabase.SplitIntoPrefixAndName(path); long prefixid; if (string.Equals(prevprefix.Key, split.Key, StringComparison.Ordinal)) { prefixid = prevprefix.Value; } else { prefixid = await database.GetOrCreatePathPrefix(split.Key); prevprefix = new KeyValuePair <string, long>(split.Key, prefixid); } if (CHECKFILETIMEONLY || DISABLEFILETIMECHECK) { var tmp = await database.GetFileLastModifiedAsync(prefixid, split.Value, lastfilesetid, false); await self.Output.WriteAsync(new FileEntry { OldId = tmp.Item1, Path = path, PathPrefixID = prefixid, Filename = split.Value, Attributes = attributes, LastWrite = lastwrite, OldModified = tmp.Item2, LastFileSize = tmp.Item3, OldMetaHash = null, OldMetaSize = -1 }); } else { var res = await database.GetFileEntryAsync(prefixid, split.Value, lastfilesetid); await self.Output.WriteAsync(new FileEntry { OldId = res == null ? -1 : res.id, Path = path, PathPrefixID = prefixid, Filename = split.Value, Attributes = attributes, LastWrite = lastwrite, OldModified = res == null ? new DateTime(0) : res.modified, LastFileSize = res == null ? -1 : res.filesize, OldMetaHash = res == null ? null : res.metahash, OldMetaSize = res == null ? -1 : res.metasize }); } } catch (Exception ex) { if (ex.IsRetiredException() || token.IsCancellationRequested) { continue; } Logging.Log.WriteWarningMessage(FILELOGTAG, "ProcessingMetadataFailed", ex, "Failed to process entry, path: {0}", path); } } } })); }
public static Task Run(Snapshots.ISnapshotService snapshot, Options options, BackupDatabase database, long lastfilesetid) { return(AutomationExtensions.RunTask(new { Input = Backup.Channels.SourcePaths.ForRead, StreamBlockChannel = Channels.StreamBlock.ForWrite, Output = Backup.Channels.ProcessedFiles.ForWrite, }, async self => { var emptymetadata = Utility.WrapMetadata(new Dictionary <string, string>(), options); var CHECKFILETIMEONLY = options.CheckFiletimeOnly; var DISABLEFILETIMECHECK = options.DisableFiletimeCheck; while (true) { var path = await self.Input.ReadAsync(); var lastwrite = new DateTime(0, DateTimeKind.Utc); var attributes = default(FileAttributes); try { lastwrite = snapshot.GetLastWriteTimeUtc(path); } catch (Exception ex) { Logging.Log.WriteWarningMessage(FILELOGTAG, "TimestampReadFailed", ex, "Failed to read timestamp on \"{0}\"", path); } try { attributes = snapshot.GetAttributes(path); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(FILELOGTAG, "FailedAttributeRead", "Failed to read attributes from {0}: {1}", path, ex.Message); } // If we only have metadata, stop here if (await ProcessMetadata(path, attributes, lastwrite, options, snapshot, emptymetadata, database, self.StreamBlockChannel).ConfigureAwait(false)) { try { if (CHECKFILETIMEONLY || DISABLEFILETIMECHECK) { var tmp = await database.GetFileLastModifiedAsync(path, lastfilesetid, false); await self.Output.WriteAsync(new FileEntry() { OldId = tmp.Item1, Path = path, Attributes = attributes, LastWrite = lastwrite, OldModified = tmp.Item2, LastFileSize = tmp.Item3, OldMetaHash = null, OldMetaSize = -1 }); } else { var res = await database.GetFileEntryAsync(path, lastfilesetid); await self.Output.WriteAsync(new FileEntry() { OldId = res == null ? -1 : res.id, Path = path, Attributes = attributes, LastWrite = lastwrite, OldModified = res == null ? new DateTime(0) : res.modified, LastFileSize = res == null ? -1 : res.filesize, OldMetaHash = res == null ? null : res.metahash, OldMetaSize = res == null ? -1 : res.metasize }); } } catch (Exception ex) { Logging.Log.WriteWarningMessage(FILELOGTAG, "ProcessingMetadataFailed", ex, "Failed to process entry, path: {0}", path); } } } })); }