public async Task <bool> Commit <TDataType>(int id) where TDataType : DataEntity { using (_logger.BeginScope("{Operation} is {Action} {DataType} with Id ({Id})", nameof(FileDataWorker), "commiting data", typeof(TDataType).Name, id)) { var filename = GetFileName <TDataType>(id); var maxAttempts = MaxAttempts <TDataType>(); _logger.LogTrace("Will try to write to {filename} {MaxAttempts} times", filename, maxAttempts); var attempts = 0; while (attempts < maxAttempts) { attempts++; _logger.LogTrace("Attempt number {Attempt}", attempts); try { if (await FileStreamer.CloseStream(filename)) { _logger.LogInformation("Closed the file and committed the data to disk"); await FileStreamer.UnlockFile(filename); return(true); } } catch (Exception exception) { _logger.LogWarning(exception, "Failed to commit data to disk as an error happened"); } } _logger.LogError("Failed to commit data to disk"); await DiscardChanges <TDataType>(id); return(false); } }
public async Task UnlockFileWhenThereIsNoLock() { await FileStreamer.UnlockFile(Filename); MockSemaphoreFactory.Verify(x => x.Create(1, 1), Times.Never); MockSemaphore.Verify(x => x.Release(), Times.Never); }
public async Task UnlockFileWhenThereIsALockMultipleTimes() { await FileStreamer.GetLockForFile(Filename); await FileStreamer.UnlockFile(Filename); await FileStreamer.UnlockFile(Filename); MockSemaphoreFactory.Verify(x => x.Create(1, 1), Times.Once); MockSemaphore.Verify(x => x.Release(), Times.Exactly(2)); }
public async Task DiscardChanges <TDataType>(int id) where TDataType : DataEntity { using (_logger.BeginScope("{Operation} is {Action} {DataType} with Id ({Id})", nameof(FileDataWorker), "discarding changes", typeof(TDataType).Name, id)) { var filename = GetFileName <TDataType>(id); _logger.LogTrace("Discarding changes to file {filename}", filename); await FileStreamer.DisposeOfStream(filename); await FileStreamer.UnlockFile(filename); _logger.LogInformation("Discarded changes to file"); } }
public async Task DiscardEvents <TDataType>(TDataType data) where TDataType : DataEntity { using (_logger.BeginScope("{Operation} is {Action} for {DataType}", nameof(FileAuditWorker), "discarded events", typeof(TDataType).Name)) { var filename = GetFileName <TDataType>(data.Id); _logger.LogTrace("Discarding changes for {filename}", filename); await FileStreamer.DisposeOfStream(filename); await FileStreamer.UnlockFile(filename); _logger.LogInformation("Discarded changes for {filename}", filename); } }
public async Task <bool> CommitEvents <TDataType>(TDataType data) where TDataType : DataEntity { using (_logger.BeginScope("{Operation} is {Action} for {DataType}", nameof(FileAuditWorker), "committing events", typeof(TDataType).Name)) { var filename = GetFileName <TDataType>(data.Id); var maxAttempts = MaxAttempts <TDataType>(); _logger.LogTrace("Will try to write to {filename} {MaxAttempts} times", filename, maxAttempts >= 0 ? maxAttempts.ToString() : "until success"); var attempts = 0; while (maxAttempts == -1 || attempts < maxAttempts) { attempts++; _logger.LogTrace("Attempt number {Attempt}", attempts); try { _logger.LogTrace("Closing audit file"); if (await FileStreamer.CloseStream(filename)) { _logger.LogTrace("Closed audit file"); await FileStreamer.UnlockFile(filename); _logger.LogInformation("Committed audit to file"); return(true); } _logger.LogWarning("Failed to close audit file"); } catch (Exception exception) { _logger.LogWarning(exception, "Failed to commit audit"); } } await DiscardEvents(data); _logger.LogWarning("Discarded events after max attempts trying to commit audit"); return(false); } }
public async Task <bool> Write <TDataType>(int id, TDataType data) where TDataType : DataEntity { using (_logger.BeginScope("{Operation} is {Action} {DataType} with Id ({Id})", nameof(FileDataWorker), "writing", typeof(TDataType).Name, id)) { var filename = GetFileName <TDataType>(id); var maxAttempts = MaxAttempts <TDataType>(); _logger.LogTrace("Will try to write to {filename} {MaxAttempts} times", filename, maxAttempts); var attempts = 0; while (attempts < maxAttempts) { attempts++; _logger.LogTrace("Attempt number {Attempt}", attempts); if (await FileStreamer.GetLockForFile(filename)) { try { _logger.LogTrace("Got a lock on the file"); if (await FileStreamer.WriteDataToStream(filename, data)) { _logger.LogInformation("Wrote the data to the file system"); return(true); } _logger.LogWarning("Failed to write data to the file system"); await FileStreamer.UnlockFile(filename); } catch (Exception exception) { _logger.LogWarning(exception, "While writing data to the file system an error happened"); await FileStreamer.UnlockFile(filename); } } } _logger.LogError("Failed to write data to the file system"); return(false); } }