private bool ResumeIfPossible( IReadWriteFileResource sourceResource, IReadWriteFileResource targetResource, Stream sourceStream, Stream targetStream) { var canResume = targetResource != null && _resumeStrategy.CanResume( sourceResource, targetResource, sourceStream, targetStream); if (canResume) { sourceStream.Seek(targetResource.Size, SeekOrigin.Begin); targetStream.Seek(targetResource.Size, SeekOrigin.Begin); } else { // force restart targetStream.SetLength(0); } return(canResume); }
private IFileResource CreateFileResourcePropertiesFor( IFileSystem target, IReadWriteFileResource sourceResource) { return(new FileResource( target, sourceResource)); }
private void NotifySyncStart( IReadWriteFileResource source, IReadWriteFileResource target) { _notifiables.ForEach( notifiable => notifiable.NotifySyncStart( source, target) ); }
public FileResource( IFileSystem targetFileSystem, IReadWriteFileResource sourceResource) { Path = System.IO.Path.Combine( targetFileSystem.BasePath, sourceResource.RelativePath); RelativePath = sourceResource.RelativePath; Size = sourceResource.Size; }
private bool TrySynchroniseResource( IReadWriteFileResource sourceResource, IFileSystem target, IReadWriteFileResource[] targetResources) { var targetResource = targetResources.FirstOrDefault( r => r.RelativePath == sourceResource.RelativePath ); if (!TryDo(sourceResource.OpenForRead, out var sourceStream)) { return(false); } if (!TryDo( () => target.Open(sourceResource.RelativePath, FileMode.OpenOrCreate, FileAccess.ReadWrite ), out var targetStream) ) { return(false); } NotifySyncStart(sourceResource, targetResource, sourceStream, targetStream); var composition = ComposePipeline(sourceStream, targetStream); try { composition.Drain(); NotifySyncComplete( sourceResource, targetResource ?? CreateFileResourcePropertiesFor( target, sourceResource) ); RecordHistory(sourceResource); } catch (Exception ex) { NotifyError(sourceResource, targetResource, ex); composition.Dispose(); return(false); } return(true); }
private FilterResult ApplyAllFilters( IEnumerable <IReadWriteFileResource> targetResources, IReadWriteFileResource sourceResource, IFileSystem source, IFileSystem target) { var filterResult = _filters.Aggregate( FilterResult.Ambivalent, (acc1, cur1) => { if (AlreadyExcluded() || // "record only" is a soft exclude // to ensure history happens for existing files AccumulatorIsRecordOnly()) { return(acc1); } var thisResult = cur1.Filter( sourceResource, targetResources, _targetHistoryRepository, source, target); return(CurrentFilterIsAmbivalent() ? acc1 : thisResult); bool AlreadyExcluded() { return(acc1 == FilterResult.Exclude); } bool CurrentFilterIsAmbivalent() { return(thisResult == FilterResult.Ambivalent); } bool AccumulatorIsRecordOnly() { return(acc1 == FilterResult.RecordOnly); } }); return(filterResult); }
private void NotifySyncStart(IReadWriteFileResource sourceResource, IReadWriteFileResource targetResource, Stream sourceStream, Stream targetStream) { var isResuming = ResumeIfPossible( sourceResource, targetResource, sourceStream, targetStream); NotifySyncStart( sourceResource, isResuming ? targetResource : null); }
private void SynchroniseResource( IFileSystem source, IReadWriteFileResource sourceResource, IFileSystem target, IReadWriteFileResource[] targetResources) { if (!source.IsFile(sourceResource.RelativePath)) { NotifyError( sourceResource, null, new FileNotFoundException( $"source: {sourceResource.RelativePath}" ) ); return; } var attempts = 0; var test = _options.Retries < 1 ? new Func <bool>(() => true) : CanTryAgain; do { if (TrySynchroniseResource( sourceResource, target, targetResources )) { return; } } while (test()); bool CanTryAgain() { return(++attempts < _options.Retries); } }
public HistoryItem(IReadWriteFileResource resource) { Path = resource.RelativePath; Size = resource.Size; }
private void RecordHistory(IReadWriteFileResource readWriteFileResource) { _targetHistoryRepository.Upsert( new HistoryItem(readWriteFileResource) ); }
private void LogWouldAttemptSync(IReadWriteFileResource obj) { Debug($" {obj.RelativePath} ({obj.Size})"); }