Skip to content

Commit 8306e83

Browse files
committed
Remove LockFile in favor of using a system Mutex for locking. Hopefully improve flakey test.
1 parent d12abc8 commit 8306e83

File tree

4 files changed

+53
-240
lines changed

4 files changed

+53
-240
lines changed

src/Exceptionless/Logging/FileExceptionlessLog.cs

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
using System.IO;
44
using System.Text;
55
using System.Threading;
6-
using Exceptionless.Storage;
76
using Exceptionless.Utility;
87

98
namespace Exceptionless.Logging {
109
public class FileExceptionlessLog : IExceptionlessLog, IDisposable {
10+
private static Mutex _flushLock = new Mutex(false, nameof(FileExceptionlessLog));
11+
1112
private Timer _flushTimer;
1213
private readonly bool _append;
1314
private bool _firstWrite = true;
@@ -126,34 +127,40 @@ public void Flush() {
126127
if (_isFlushing || _buffer.IsEmpty)
127128
return;
128129

130+
bool hasFlushLock = false;
129131
try {
130132
_isFlushing = true;
131133

132134
Run.WithRetries(() => {
133-
using (var logFileLock = LockFile.Acquire(FilePath + ".lock", TimeSpan.FromMilliseconds(500))) {
134-
bool append = _append || !_firstWrite;
135-
_firstWrite = false;
136-
137-
try {
138-
using (var writer = GetWriter(append)) {
139-
LogEntry entry;
140-
while (_buffer.TryDequeue(out entry)) {
141-
if (entry != null && entry.LogLevel >= MinimumLogLevel)
142-
writer.Value.WriteLine($"{FormatLongDate(entry.Timestamp)} {entry.LogLevel.ToString().PadRight(5)} {entry.Message}");
143-
}
144-
}
145-
} catch (Exception ex) {
146-
System.Diagnostics.Trace.TraceError("Unable flush the logs. " + ex.Message);
135+
if (!_flushLock.WaitOne(TimeSpan.FromSeconds(5)))
136+
return;
137+
138+
hasFlushLock = true;
139+
140+
bool append = _append || !_firstWrite;
141+
_firstWrite = false;
142+
143+
try {
144+
using (var writer = GetWriter(append)) {
147145
LogEntry entry;
148146
while (_buffer.TryDequeue(out entry)) {
149-
System.Diagnostics.Trace.WriteLine(entry);
147+
if (entry != null && entry.LogLevel >= MinimumLogLevel)
148+
writer.Value.WriteLine($"{FormatLongDate(entry.Timestamp)} {entry.LogLevel.ToString().PadRight(5)} {entry.Message}");
150149
}
151150
}
151+
} catch (Exception ex) {
152+
System.Diagnostics.Trace.TraceError("Unable flush the logs. " + ex.Message);
153+
LogEntry entry;
154+
while (_buffer.TryDequeue(out entry)) {
155+
System.Diagnostics.Trace.WriteLine(entry);
156+
}
152157
}
153158
});
154159
} catch (Exception ex) {
155160
System.Diagnostics.Trace.WriteLine("Exceptionless: Error flushing log contents to disk: {0}", ex.Message);
156161
} finally {
162+
if (hasFlushLock)
163+
_flushLock.ReleaseMutex();
157164
_isFlushing = false;
158165
}
159166
}
@@ -212,11 +219,12 @@ internal void CheckFileSize() {
212219
string lastLines = String.Empty;
213220
try {
214221
Run.WithRetries(() => {
215-
using (var logFileLock = LockFile.Acquire(FilePath + ".lock", TimeSpan.FromMilliseconds(500))) {
216-
try {
217-
lastLines = GetLastLinesFromFile(FilePath);
218-
} catch {}
219-
}
222+
if (!_flushLock.WaitOne(TimeSpan.FromSeconds(5)))
223+
return;
224+
225+
lastLines = GetLastLinesFromFile(FilePath);
226+
227+
_flushLock.ReleaseMutex();
220228
});
221229
} catch (Exception ex) {
222230
System.Diagnostics.Trace.WriteLine("Exceptionless: Error getting last X lines from the log file: {0}", ex.Message);
@@ -230,10 +238,13 @@ internal void CheckFileSize() {
230238
// overwrite the log file and initialize it with the last X lines it had
231239
try {
232240
Run.WithRetries(() => {
233-
using (var logFileLock = LockFile.Acquire(FilePath + ".lock", TimeSpan.FromMilliseconds(500))) {
234-
using (var writer = GetWriter(true))
235-
writer.Value.Write(lastLines);
236-
}
241+
if (!_flushLock.WaitOne(TimeSpan.FromSeconds(5)))
242+
return;
243+
244+
using (var writer = GetWriter(true))
245+
writer.Value.Write(lastLines);
246+
247+
_flushLock.ReleaseMutex();
237248
});
238249
} catch (Exception ex) {
239250
System.Diagnostics.Trace.WriteLine("Exceptionless: Error rewriting the log file after trimming it: {0}", ex.Message);

src/Exceptionless/Storage/LockFile.cs

Lines changed: 0 additions & 165 deletions
This file was deleted.

test/Exceptionless.Tests/Plugins/PluginTests.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
using Xunit;
1818
using Xunit.Abstractions;
1919
using LogLevel = Exceptionless.Logging.LogLevel;
20+
using Exceptionless.Json;
21+
using Exceptionless.Extensions;
2022

2123
namespace Exceptionless.Tests.Plugins {
2224
public class PluginTests {
@@ -834,23 +836,35 @@ public void VerifyDeduplicationMultithreaded() {
834836
var client = CreateClient();
835837
// TODO: We need to look into why the ErrorPlugin causes data to sometimes calculate invalid hashcodes
836838
var errorPlugin = new SimpleErrorPlugin();
839+
var simpleError = GetException().ToSimpleErrorModel(client);
837840

838841
var contexts = new ConcurrentBag<EventPluginContext>();
839-
using (var duplicateCheckerPlugin = new DuplicateCheckerPlugin(TimeSpan.FromSeconds(1))) {
842+
using (var duplicateCheckerPlugin = new DuplicateCheckerPlugin(TimeSpan.FromSeconds(60))) {
843+
int hashCode = 0;
840844
var result = Parallel.For(0, 10, index => {
841-
var builder = GetException().ToExceptionless();
845+
var builder = client.CreateEvent();
846+
builder.SetType(Event.KnownTypes.Error);
847+
builder.Target.Data[Event.KnownDataKeys.SimpleError] = simpleError;
848+
842849
var context = new EventPluginContext(client, builder.Target, builder.PluginContextData);
843850
contexts.Add(context);
844851

845-
errorPlugin.Run(context);
846852
duplicateCheckerPlugin.Run(context);
853+
854+
if (hashCode == 0)
855+
hashCode = builder.Target.GetHashCode();
856+
else if (hashCode != builder.Target.GetHashCode())
857+
throw new ApplicationException();
847858
});
848859

849860
while (!result.IsCompleted) {
850861
Thread.Yield();
851862
}
852863
}
853864

865+
var nonCancelled = contexts.Where(c => !c.Cancel).Select(c => (Context: c, Event: c.Event.GetHashCode(), Json: JsonConvert.SerializeObject(c.Event))).ToList();
866+
var all = contexts.Select(c => (Context: c, Event: c.Event.GetHashCode())).ToList();
867+
854868
Assert.Equal(1, contexts.Count(c => !c.Cancel));
855869
Assert.Equal(9, contexts.Count(c => c.Cancel));
856870
Assert.Equal(9, contexts.Sum(c => c.Event.Count.GetValueOrDefault()));

test/Exceptionless.Tests/Storage/LockFileTests.cs

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)