/// <summary> /// Try do delete files that have been decrypted temporarily, if the conditions are met for such a deletion, /// i.e. it is apparently not locked or in use etc. /// </summary> /// <param name="fileSystemState">The instance of FileSystemState where active files are recorded.</param> /// <param name="progress">The context where progress may be reported.</param> public static void PurgeActiveFiles(this FileSystemState fileSystemState, ProgressContext progress) { progress.NotifyLevelStart(); fileSystemState.ForEach(ChangedEventMode.RaiseOnlyOnModified, (ActiveFile activeFile) => { if (FileLock.IsLocked(activeFile.DecryptedFileInfo)) { if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Not deleting '{0}' because it is marked as locked.".InvariantFormat(activeFile.DecryptedFileInfo.FullName)); } return(activeFile); } if (activeFile.IsModified) { if (activeFile.Status.HasMask(ActiveFileStatus.NotShareable)) { activeFile = new ActiveFile(activeFile, activeFile.Status & ~ActiveFileStatus.NotShareable); } activeFile = CheckIfTimeToUpdate(activeFile, progress); } if (activeFile.Status.HasMask(ActiveFileStatus.AssumedOpenAndDecrypted)) { activeFile = TryDelete(activeFile, progress); } return(activeFile); }); progress.NotifyLevelFinished(); }
/// <summary> /// Enumerate all files listed as active, checking for status changes and take appropriate actions such as updating status /// in the FileSystemState, re-encrypting or deleting temporary plaintext copies. /// </summary> /// <param name="fileSystemState">The FileSystemState to enumerate and possibly update.</param> /// <param name="mode">Under what circumstances is the FileSystemState.Changed event raised.</param> /// <param name="progress">The ProgressContext to provide visual progress feedback via.</param> public static void CheckActiveFiles(this FileSystemState fileSystemState, ChangedEventMode mode, ProgressContext progress) { progress.NotifyLevelStart(); progress.AddTotal(fileSystemState.ActiveFileCount); fileSystemState.ForEach(mode, (ActiveFile activeFile) => { try { if (FileLock.IsLocked(activeFile.DecryptedFileInfo, activeFile.EncryptedFileInfo)) { return(activeFile); } if (OS.Current.UtcNow - activeFile.LastActivityTimeUtc <= new TimeSpan(0, 0, 5)) { return(activeFile); } activeFile = fileSystemState.CheckActiveFileActions(activeFile, progress); return(activeFile); } finally { progress.AddCount(1); } }); progress.NotifyLevelFinished(); }
private async Task ProcessNew(File file, EofMessage eofMessage) { var tempPath = await BuildFile(file, eofMessage); if (tempPath is null) { return; } var filePath = file.GetFullPath(); if (System.IO.File.Exists(filePath) && FileLock.IsLocked(filePath, checkWriteAccess: true)) { WorkerLog.Instance.Warning($"File '{filePath}' is locked for writing. unable overwrite file"); } else { WorkerLog.Instance.Information($"Decompressing file '{tempPath}'"); await file.DecompressFrom(tempPath); WorkerLog.Instance.Information($"File decompressed to '{filePath}'"); await MarkFileAsCompleted(file); } DeleteTempPath(tempPath); }
public static void TestFileLockInvalidArguments() { IRuntimeFileInfo nullInfo = null; Assert.Throws <ArgumentNullException>(() => { FileLock.Lock(nullInfo); }); Assert.Throws <ArgumentNullException>(() => { FileLock.IsLocked(nullInfo); }); Assert.Throws <ArgumentNullException>(() => { FileLock.IsLocked(OS.Current.FileInfo(_fileExtPath), nullInfo); }); }
private void ClearRunDirectory() { foreach (var directory in Directory.GetDirectories(ScriptDirectory)) { if (!FileLock.IsLocked(Path.Combine(directory, ".lock"))) { Directory.Delete(directory, true); } } }
public static void TestFileLockMethods() { IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_fileExtPath); Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file yet."); using (FileLock lock1 = FileLock.Lock(fileInfo)) { Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should be now be a lock for this file."); } Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file again."); }
public static void TestFileLockCaseSensitivity() { IRuntimeFileInfo fileInfo1 = OS.Current.FileInfo(_fileExtPath); IRuntimeFileInfo fileInfo2 = OS.Current.FileInfo(_fileExtPath.ToUpper(CultureInfo.InvariantCulture)); Assert.That(FileLock.IsLocked(fileInfo1), Is.False, "There should be no lock for this file yet."); Assert.That(FileLock.IsLocked(fileInfo2), Is.False, "There should be no lock for this file yet."); using (FileLock lock1 = FileLock.Lock(fileInfo1)) { Assert.That(FileLock.IsLocked(fileInfo1), Is.True, "There should be now be a lock for this file."); Assert.That(FileLock.IsLocked(fileInfo2), Is.False, "There should be no lock for this file still."); } Assert.That(FileLock.IsLocked(fileInfo1), Is.False, "There should be no lock for this file again."); }
public static void TestFileLockWhenLocked() { IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_fileExtPath); Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file to start with."); using (FileLock lock1 = FileLock.Lock(fileInfo)) { Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should be a lock for this file."); using (FileLock lock1a = FileLock.Lock(fileInfo)) { Assert.That(lock1a, Is.Null, "When trying to get a lock for a locked file, this should return null."); Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should still be a lock for this file."); } Assert.That(FileLock.IsLocked(fileInfo), Is.True, "There should still be a lock for this file."); } Assert.That(FileLock.IsLocked(fileInfo), Is.False, "There should be no lock for this file now."); }
public static void TestSimple() { using (MemoryStream stream = FakeRuntimeFileInfo.ExpandableMemoryStream(Encoding.UTF8.GetBytes("A short dummy stream"))) { IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_davidCopperfieldTxtPath); using (LockingStream lockingStream = new LockingStream(fileInfo, stream)) { Assert.That(FileLock.IsLocked(fileInfo), "The file should be locked now."); Assert.That(lockingStream.CanRead, "The stream should be readable."); Assert.That(lockingStream.CanSeek, "The stream should be seekable."); Assert.That(lockingStream.CanWrite, "The stream should be writeable."); Assert.That(lockingStream.Length, Is.EqualTo("A short dummy stream".Length), "The length should be the same as the string."); byte[] b = new byte[1]; int read = lockingStream.Read(b, 0, 1); Assert.That(read, Is.EqualTo(1), "There should be one byte read."); Assert.That(b[0], Is.EqualTo(Encoding.UTF8.GetBytes("A")[0]), "The byte read should be an 'A'."); Assert.That(lockingStream.Position, Is.EqualTo(1), "After reading the first byte, the position should be at one."); lockingStream.Write(b, 0, 1); lockingStream.Position = 1; read = lockingStream.Read(b, 0, 1); Assert.That(read, Is.EqualTo(1), "There should be one byte read."); Assert.That(b[0], Is.EqualTo(Encoding.UTF8.GetBytes("A")[0]), "The byte read should be an 'A'."); lockingStream.Seek(-1, SeekOrigin.End); Assert.That(lockingStream.Position, Is.EqualTo(lockingStream.Length - 1), "The position should be set by the Seek()."); lockingStream.SetLength(5); lockingStream.Seek(0, SeekOrigin.End); Assert.That(lockingStream.Position, Is.EqualTo(5), "After setting the length to 5, seeking to the end should set the position at 5."); Assert.DoesNotThrow(() => { lockingStream.Flush(); }, "It's hard to test Flush() behavior here, not worth the trouble, but it should not throw!"); } Assert.That(!FileLock.IsLocked(fileInfo), "The file should be unlocked now."); Assert.Throws <ObjectDisposedException>(() => { stream.Position = 0; }, "The underlying stream should be disposed."); } }
private async Task ProcessChange(File file, EofMessage eofMessage) { var tempPath = await BuildFile(file, eofMessage); if (tempPath is null) { return; } var filePath = file.GetFullPath(); if (System.IO.File.Exists(filePath) && !FileLock.IsLocked(filePath, checkWriteAccess: true)) { WorkerLog.Instance.Information($"Applying delta to {filePath}"); file.ApplyDelta(System.IO.File.ReadAllBytes(tempPath)); await MarkFileAsCompleted(file); } else { WorkerLog.Instance.Warning($"File '{filePath}' does not exist or is locked for writing. unable to apply delta"); } DeleteTempPath(tempPath); }
public async Task <EofMessage> ProcessFile() { var path = _file.GetFullPath(); EofMessage eofMessage = null; if (!string.IsNullOrWhiteSpace(path) && System.IO.File.Exists(path) && !FileLock.IsLocked(path)) { try { if (_file.IsNew()) { eofMessage = await ProcessNewFile(); } else { eofMessage = await ProcessChangedFile(); } } catch (Exception ex) { WorkerLog.Instance.Error(ex, $"Unexpected error occured while disassembling file '{_file.Path}'"); } } else { WorkerLog.Instance.Warning($"File '{path}' does not exist or is locked. File will not be processed"); } if (eofMessage is null) { await _fileRepository.UpdateFileAsFailed(_file.Id); } return(eofMessage); }