Skip to content

Commit 3992d60

Browse files
committed
Fixed an issue where configuration action wasn't updating the settings timer and added some error handling around SettingsManager
1 parent 92c539d commit 3992d60

File tree

6 files changed

+82
-51
lines changed

6 files changed

+82
-51
lines changed

Source/Samples/SampleConsole/Program.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ private static void Main() {
3838
Console.CursorVisible = false;
3939
StartDisplayingLogMessages();
4040

41+
ExceptionlessClient.Default.Configuration.UpdateSettingsWhenIdleInterval = TimeSpan.FromSeconds(15);
4142
ExceptionlessClient.Default.Configuration.UseTraceLogEntriesPlugin();
4243
ExceptionlessClient.Default.Configuration.AddPlugin<SystemUptimePlugin>();
4344
ExceptionlessClient.Default.Configuration.UseFolderStorage("store");
@@ -86,7 +87,9 @@ private static void Main() {
8687
} else if (keyInfo.Key == ConsoleKey.D5) {
8788
ExceptionlessClient.Default.Configuration.UseSessions(false, null, true);
8889
ExceptionlessClient.Default.SubmitSessionStart();
89-
} else if (keyInfo.Key == ConsoleKey.D7)
90+
} else if (keyInfo.Key == ConsoleKey.D6)
91+
SendContinuousEvents(250, token, ev: new Event { Type = Event.KnownTypes.Log, Source = "SampleConsole.Program.Main", Message = "Sample console application event" });
92+
else if (keyInfo.Key == ConsoleKey.D7)
9093
ExceptionlessClient.Default.SubmitSessionEnd();
9194
else if (keyInfo.Key == ConsoleKey.D8)
9295
ExceptionlessClient.Default.Configuration.SetUserIdentity(Guid.NewGuid().ToString("N"));
@@ -151,7 +154,7 @@ private static void WriteOptionsMenu() {
151154
Console.WriteLine("3: Send continuous");
152155
Console.WriteLine("4: Send session start");
153156
Console.WriteLine("5: Send session start (manual)");
154-
Console.WriteLine("6: Send heart beat");
157+
Console.WriteLine("6: Send continuous log event");
155158
Console.WriteLine("7: Send session end");
156159
Console.WriteLine("8: Change user identity");
157160
Console.WriteLine("P: Process queue");
@@ -221,7 +224,7 @@ private static void ClearConsoleLines(int startLine = 0, int endLine = -1) {
221224
}
222225
}
223226

224-
private static void SendContinuousEvents(int delay, CancellationToken token, int maxEvents = Int32.MaxValue, int maxDaysOld = 90) {
227+
private static void SendContinuousEvents(int delay, CancellationToken token, int maxEvents = Int32.MaxValue, int maxDaysOld = 90, Event ev = null) {
225228
Console.SetCursorPosition(0, OPTIONS_MENU_LINE_COUNT + 2);
226229
Console.WriteLine("Press 's' to stop sending.");
227230
int eventCount = 0;
@@ -231,7 +234,7 @@ private static void SendContinuousEvents(int delay, CancellationToken token, int
231234
if (token.IsCancellationRequested)
232235
break;
233236

234-
SendEvent(false);
237+
SendEvent(ev, false);
235238
eventCount++;
236239
lock (_writeLock) {
237240
Console.SetCursorPosition(0, OPTIONS_MENU_LINE_COUNT + 4);
@@ -246,11 +249,11 @@ private static void SendContinuousEvents(int delay, CancellationToken token, int
246249
}
247250

248251
private static readonly RandomEventGenerator _rnd = new RandomEventGenerator();
249-
private static void SendEvent(bool writeToConsole = true) {
252+
private static void SendEvent(Event ev = null, bool writeToConsole = true) {
250253
_rnd.MinDate = DateTime.Now.Subtract(_dateSpans[_dateSpanIndex]);
251254
_rnd.MaxDate = DateTime.Now;
252255

253-
ExceptionlessClient.Default.SubmitEvent(_rnd.Generate());
256+
ExceptionlessClient.Default.SubmitEvent(ev ?? _rnd.Generate());
254257

255258
if (writeToConsole) {
256259
lock (_writeLock) {

Source/Shared/Configuration/SettingsManager.cs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ private static SettingsDictionary GetSavedServerSettings(ExceptionlessConfigurat
2828
if (String.IsNullOrEmpty(configPath))
2929
return new SettingsDictionary();
3030

31-
var fileStorage = config.Resolver.GetFileStorage();
32-
if (!fileStorage.Exists(configPath))
33-
return new SettingsDictionary();
34-
3531
try {
32+
var fileStorage = config.Resolver.GetFileStorage();
33+
if (!fileStorage.Exists(configPath))
34+
return new SettingsDictionary();
35+
3636
return fileStorage.GetObject<SettingsDictionary>(configPath);
3737
} catch (Exception ex) {
3838
config.Resolver.GetLog().FormattedError(typeof(SettingsManager), ex, "Unable to read and apply saved server settings: {0}", ex.Message);
@@ -50,8 +50,13 @@ public static int GetVersion(ExceptionlessConfiguration config) {
5050
return 0;
5151
}
5252

53-
var persistedClientData = config.Resolver.Resolve<PersistedDictionary>();
54-
return persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), 0);
53+
try {
54+
var persistedClientData = config.Resolver.Resolve<PersistedDictionary>();
55+
return persistedClientData.GetInt32(String.Concat(config.GetQueueName(), "-ServerConfigVersion"), 0);
56+
} catch (Exception ex) {
57+
config.Resolver.GetLog().Error(typeof(SettingsManager), ex, "Error occurred getting settings version.");
58+
return 0;
59+
}
5560
}
5661

5762
public static void CheckVersion(int version, ExceptionlessConfiguration config) {
@@ -65,37 +70,41 @@ public static void CheckVersion(int version, ExceptionlessConfiguration config)
6570
public static void UpdateSettings(ExceptionlessConfiguration config, int? version = null) {
6671
if (config == null)
6772
return;
68-
73+
6974
if (String.IsNullOrEmpty(config.ApiKey) || String.Equals(config.ApiKey, "API_KEY_HERE", StringComparison.OrdinalIgnoreCase)) {
7075
config.Resolver.GetLog().Error(typeof(SettingsManager), "Unable to update settings: ApiKey is not set.");
7176
return;
7277
}
7378

74-
if (!version.HasValue || version < 0)
75-
version = GetVersion(config);
76-
77-
var serializer = config.Resolver.GetJsonSerializer();
78-
var client = config.Resolver.GetSubmissionClient();
79+
try {
80+
if (!version.HasValue || version < 0)
81+
version = GetVersion(config);
7982

80-
var response = client.GetSettings(config, version.Value, serializer);
81-
if (!response.Success || response.Settings == null)
82-
return;
83+
var serializer = config.Resolver.GetJsonSerializer();
84+
var client = config.Resolver.GetSubmissionClient();
8385

84-
var savedServerSettings = GetSavedServerSettings(config);
85-
config.Settings.Apply(response.Settings);
86+
var response = client.GetSettings(config, version.Value, serializer);
87+
if (!response.Success || response.Settings == null)
88+
return;
8689

87-
// TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults.
88-
// Remove any existing server settings that are not in the new server settings.
89-
foreach (string key in savedServerSettings.Keys.Except(response.Settings.Keys)) {
90-
if (config.Settings.ContainsKey(key))
91-
config.Settings.Remove(key);
92-
}
90+
var savedServerSettings = GetSavedServerSettings(config);
91+
config.Settings.Apply(response.Settings);
92+
93+
// TODO: Store snapshot of settings after reading from config and attributes and use that to revert to defaults.
94+
// Remove any existing server settings that are not in the new server settings.
95+
foreach (string key in savedServerSettings.Keys.Except(response.Settings.Keys)) {
96+
if (config.Settings.ContainsKey(key))
97+
config.Settings.Remove(key);
98+
}
9399

94-
var persistedClientData = config.Resolver.Resolve<PersistedDictionary>();
95-
persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString();
100+
var persistedClientData = config.Resolver.Resolve<PersistedDictionary>();
101+
persistedClientData[String.Concat(config.GetQueueName(), "-ServerConfigVersion")] = response.SettingsVersion.ToString();
96102

97-
var fileStorage = config.Resolver.GetFileStorage();
98-
fileStorage.SaveObject(GetConfigPath(config), response.Settings);
103+
var fileStorage = config.Resolver.GetFileStorage();
104+
fileStorage.SaveObject(GetConfigPath(config), response.Settings);
105+
} catch (Exception ex) {
106+
config.Resolver.GetLog().Error(typeof(SettingsManager), ex, "Error occurred updating settings.");
107+
}
99108
}
100109

101110
private static string GetConfigPath(ExceptionlessConfiguration config) {

Source/Shared/ExceptionlessClient.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,42 @@ public ExceptionlessClient(string apiKey) : this(new ExceptionlessConfiguration(
2525
}
2626

2727
public ExceptionlessClient(Action<ExceptionlessConfiguration> configure) : this(new ExceptionlessConfiguration(DependencyResolver.CreateDefault())) {
28-
if (configure != null)
29-
configure(Configuration);
28+
if (configure == null)
29+
return;
30+
31+
configure(Configuration);
32+
_updateSettingsTimer.Change(GetInitialSettingsDelay(), Configuration.UpdateSettingsWhenIdleInterval);
3033
}
3134

3235
public ExceptionlessClient(ExceptionlessConfiguration configuration) {
3336
if (configuration == null)
3437
throw new ArgumentNullException("configuration");
3538

3639
Configuration = configuration;
37-
configuration.Resolver.Register(typeof(ExceptionlessConfiguration), () => Configuration);
40+
Configuration.Resolver.Register(typeof(ExceptionlessConfiguration), () => Configuration);
3841
_log = new Lazy<IExceptionlessLog>(() => Configuration.Resolver.GetLog());
3942
_queue = new Lazy<IEventQueue>(() => {
4043
// config can't be changed after the queue starts up.
4144
Configuration.LockConfig();
4245

4346
var q = Configuration.Resolver.GetEventQueue();
44-
q.EventsPosted += (sender, args) => {
45-
_updateSettingsTimer.Change(Configuration.UpdateSettingsWhenIdleInterval, Configuration.UpdateSettingsWhenIdleInterval);
46-
};
47-
47+
q.EventsPosted += OnQueueEventsPosted;
4848
return q;
4949
});
5050

5151
_submissionClient = new Lazy<ISubmissionClient>(() => Configuration.Resolver.GetSubmissionClient());
5252
_lastReferenceIdManager = new Lazy<ILastReferenceIdManager>(() => Configuration.Resolver.GetLastReferenceIdManager());
53+
_updateSettingsTimer = new Timer(state => SettingsManager.UpdateSettings(Configuration), null, GetInitialSettingsDelay(), Configuration.UpdateSettingsWhenIdleInterval);
54+
}
5355

54-
var initialDelay = configuration.UpdateSettingsWhenIdleInterval > TimeSpan.Zero ? TimeSpan.FromSeconds(5) : TimeSpan.FromMilliseconds(-1);
55-
_updateSettingsTimer = new Timer(state => SettingsManager.UpdateSettings(Configuration), null, initialDelay, configuration.UpdateSettingsWhenIdleInterval);
56+
private TimeSpan GetInitialSettingsDelay() {
57+
return Configuration.UpdateSettingsWhenIdleInterval > TimeSpan.Zero ? TimeSpan.FromSeconds(5) : TimeSpan.FromMilliseconds(-1);
5658
}
5759

60+
private void OnQueueEventsPosted(object sender, EventsPostedEventArgs args) {
61+
_updateSettingsTimer.Change(Configuration.UpdateSettingsWhenIdleInterval, Configuration.UpdateSettingsWhenIdleInterval);
62+
}
63+
5864
public ExceptionlessConfiguration Configuration { get; private set; }
5965

6066
/// <summary>
@@ -262,6 +268,10 @@ protected void OnSubmittedEvent(EventSubmittedEventArgs e) {
262268
}
263269

264270
void IDisposable.Dispose() {
271+
if (_queue.IsValueCreated)
272+
_queue.Value.EventsPosted -= OnQueueEventsPosted;
273+
274+
_updateSettingsTimer.Dispose();
265275
Configuration.Resolver.Dispose();
266276
}
267277

Source/Tests/ExceptionlessClientTests.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ private ExceptionlessClient CreateClient() {
1414
c.UseTraceLogger();
1515
c.ReadFromAttributes();
1616
c.UserAgent = "testclient/1.0.0.0";
17+
18+
// Disable updating settings.
19+
c.UpdateSettingsWhenIdleInterval = TimeSpan.Zero;
1720
});
1821
}
1922

@@ -43,17 +46,17 @@ public void CanAddMultipleDataObjectsToEvent() {
4346
public void CanFireOnSubmittingEvent() {
4447
var client = CreateClient();
4548
var ev = new Event { Message = "Unit Test" };
46-
var list = new List<EventSubmittingEventArgs>();
49+
var submittingEventArgs = new List<EventSubmittingEventArgs>();
4750

4851
client.SubmittingEvent += (sender, e) => {
49-
list.Add(e);
52+
submittingEventArgs.Add(e);
5053
};
5154

5255
new EventBuilder(ev, client).Submit();
53-
Assert.Equal(1, list.Count);
56+
Assert.Equal(1, submittingEventArgs.Count);
5457

5558
new EventBuilder(ev, client, new ContextData()).Submit();
56-
Assert.Equal(2, list.Count);
59+
Assert.Equal(2, submittingEventArgs.Count);
5760
}
5861

5962
[Fact]
@@ -72,13 +75,13 @@ public void CanCallStartupWithCustomSubmissionClient() {
7275
client.Shutdown();
7376
}
7477

75-
[Fact (Skip = "This test shows off throwing a stack overflow exception: Issue #26")]
76-
public void WillThrowStackOverflowExceptionDuringOnSubmitting() {
78+
[Fact]
79+
public void WillNotThrowStackOverflowExceptionDuringOnSubmitting() {
7780
var client = CreateClient();
78-
var list = new List<EventSubmittingEventArgs>();
81+
var submittingEventArgs = new List<EventSubmittingEventArgs>();
7982

8083
client.SubmittingEvent += (sender, e) => {
81-
list.Add(e);
84+
submittingEventArgs.Add(e);
8285
if (e.IsUnhandledError) {
8386
new EventBuilder(e.Event, e.Client, e.PluginContextData).AddTags("Unhandled").Submit();
8487
e.Cancel = true;
@@ -88,7 +91,7 @@ public void WillThrowStackOverflowExceptionDuringOnSubmitting() {
8891
var contextData = new ContextData();
8992
contextData.MarkAsUnhandledError();
9093
new Exception("Test").ToExceptionless(contextData, client).Submit();
91-
Assert.Equal(2, list.Count);
94+
Assert.Equal(1, submittingEventArgs.Count);
9295
}
9396

9497
private class Person {

Source/Tests/Plugins/PluginTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ private ExceptionlessClient CreateClient() {
2929
c.UseLogger(new XunitExceptionlessLog(_writer) { MinimumLogLevel = LogLevel.Trace });
3030
c.ReadFromAttributes();
3131
c.UserAgent = "testclient/1.0.0.0";
32+
33+
// Disable updating settings.
34+
c.UpdateSettingsWhenIdleInterval = TimeSpan.Zero;
3235
});
3336
}
3437

Source/Tests/Serializer/SerializerTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ private ExceptionlessClient CreateClient() {
162162
c.UseTraceLogger();
163163
c.ReadFromAttributes();
164164
c.UserAgent = "testclient/1.0.0.0";
165+
166+
// Disable updating settings.
167+
c.UpdateSettingsWhenIdleInterval = TimeSpan.Zero;
165168
});
166169
}
167170
}

0 commit comments

Comments
 (0)