From beca9c4e73f6714243c990bcb521832740d59850 Mon Sep 17 00:00:00 2001 From: Andrew Knous Date: Fri, 26 Apr 2024 18:32:52 -0400 Subject: [PATCH] fix: fixes issue with concurrent requests causing malformed responses --- src/EpiphanPearl/EpiphanPearlClient.cs | 61 ++++++++++++---- src/EpiphanPearl/EpiphanPearlController.cs | 73 +++++++++++--------- src/EpiphanPearl/EpiphanPearlSecureClient.cs | 21 +++--- src/EpiphanPearl/Event.cs | 26 ++++++- 4 files changed, 123 insertions(+), 58 deletions(-) diff --git a/src/EpiphanPearl/EpiphanPearlClient.cs b/src/EpiphanPearl/EpiphanPearlClient.cs index f91f55d..926085e 100644 --- a/src/EpiphanPearl/EpiphanPearlClient.cs +++ b/src/EpiphanPearl/EpiphanPearlClient.cs @@ -5,6 +5,7 @@ using PepperDash.Core; using PepperDash.Essentials.EpiphanPearl.Interfaces; using PepperDash.Essentials.EpiphanPearl.Utilities; +using System.Text; namespace PepperDash.Essentials.EpiphanPearl { @@ -31,23 +32,25 @@ public T Get(string path) where T:class var response = SendRequest(request); - if (string.IsNullOrEmpty(response)) + if (response == null || response.Length <= 0) { + Debug.Console(2, "[T Get] Response to {0} is null", request.Url, response); return null; } try { + Debug.Console(2, "[T Get] Response to {0}: {1}", request.Url, response); return JsonConvert.DeserializeObject(response); } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[T Get] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[T Get] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; @@ -65,7 +68,7 @@ public TResponse Post (string path, TBody body) where TBody: c var response = SendRequest(request); - if (string.IsNullOrEmpty(response)) + if (response == null) { return null; } @@ -76,12 +79,12 @@ public TResponse Post (string path, TBody body) where TBody: c } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; @@ -97,7 +100,7 @@ public TResponse Post(string path) var response = SendRequest(request); - if (string.IsNullOrEmpty(response)) + if (response == null) { return null; } @@ -108,12 +111,12 @@ public TResponse Post(string path) } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; @@ -134,24 +137,52 @@ public void setHost(string host) private string SendRequest(HttpClientRequest request) { + if (request == null) + { + Debug.Console(2, "[SendRequest] Request is null"); + return null; + } + + if (_client == null) + { + Debug.Console(2, "[SendRequest] HttpClient is null"); + return null; + } + try { + Debug.Console(2, "[SendRequest] Dispatching request to {0}", request.Url); // Log before dispatch var response = _client.Dispatch(request); - Debug.Console(2, "Response from request to {0}: {1} {2}", request.Url, response.Code, - response.ContentString); + if (response == null) + { + Debug.Console(2, "[SendRequest] Response is null after dispatching request to {0}", request.Url); + return null; + } - return response.ContentString; + //Debug.Console(0, "Raw response bytes: {0}", BitConverter.ToString(response.ContentBytes)); + + try + { + // Attempt to parse the response content as a string + var contentString = response.ContentString; + return contentString; + } + catch (Exception ex) + { + Debug.Console(2, "[SendRequest] Error converting response to string for URL {0}: {1}", request.Url, ex.Message); + return null; + } } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[SendRequest] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException != null) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); - Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); + Debug.Console(0, "[SendRequest] Inner Exception: {1}", request.Url, ex.InnerException.Message); + Debug.Console(2, "Inner Stack Trace: {0}", ex.InnerException.StackTrace); } return null; diff --git a/src/EpiphanPearl/EpiphanPearlController.cs b/src/EpiphanPearl/EpiphanPearlController.cs index 1227f81..8c6496b 100644 --- a/src/EpiphanPearl/EpiphanPearlController.cs +++ b/src/EpiphanPearl/EpiphanPearlController.cs @@ -18,6 +18,7 @@ namespace PepperDash.Essentials.EpiphanPearl public class EpiphanPearlController : ReconfigurableBridgableDevice, ICommunicationMonitor { private const string RunningStatus = "running"; + private const string PausedStatus = "paused"; private readonly IEpiphanPearlClient _client; private readonly EpiphanCommunicationMonitor _monitor; @@ -36,6 +37,7 @@ public class EpiphanPearlController : ReconfigurableBridgableDevice, ICommunicat private StringFeedback _runningEventTimeRemainingFeedback; private BoolFeedback _runningEventRunningFeedback; + private BoolFeedback _runningEventPausedFeedback; private StringFeedback _runningEventStartFeedback; /* private FeedbackCollection _scheduleEndFeedbacks; @@ -80,18 +82,21 @@ public StatusMonitorBase CommunicationMonitor public override void Initialize() { - _pollTimer = new CTimer(o => Poll(), null, 0, 15000); + _pollTimer = new CTimer(o => Poll(), null, 0, 10000); _monitor.Start(); } private void Poll() { - Debug.Console(0, this, "Getting Scheduled Events"); + Debug.Console(1, this, "Getting Scheduled Events"); GetScheduledEvents(); - Debug.Console(0, this, "Getting Running Events"); + Debug.Console(1, this, "Getting Running Events"); GetRunningEvent(); + + Debug.Console(1, this, "Getting Running Event Status"); + GetRunningEventStatus(); } private void CreateFeedbacks() @@ -169,6 +174,10 @@ private void CreateFeedbacks() new BoolFeedback( () => _runningEvent != null && _runningEvent.Status.Equals(RunningStatus, StringComparison.InvariantCultureIgnoreCase)); + _runningEventPausedFeedback = + new BoolFeedback( + () => _runningEvent != null && _runningEvent.Status.Equals(PausedStatus, StringComparison.InvariantCultureIgnoreCase)); + _nextEventExistsFeedback = new BoolFeedback(() => _scheduledEvents.Count > 0); } @@ -192,7 +201,7 @@ public override void LinkToApi(BasicTriList trilist, uint joinStart, string join CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RecorderOnline.JoinNumber]); _runningEventRunningFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsRecording.JoinNumber]); - _runningEventRunningFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.IsPaused.JoinNumber]); + _runningEventPausedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsPaused.JoinNumber]); _runningEventNameFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentRecordingName.JoinNumber]); _runningEventStartFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentRecordingStartTime.JoinNumber]); @@ -265,7 +274,7 @@ private void PauseRunningEvent() { if (_runningEvent == null) { - Debug.Console(0, this, "No running event"); + Debug.Console(1, this, "No running event"); return; } @@ -275,7 +284,7 @@ private void PauseRunningEvent() if (response == null) { - Debug.Console(0, this, "Unable to pause event"); + Debug.Console(1, this, "Unable to pause event"); _monitor.SetOnlineStatus(false); @@ -284,7 +293,7 @@ private void PauseRunningEvent() if (!response.Status.Equals("ok", StringComparison.InvariantCultureIgnoreCase)) { - Debug.Console(0, this, "Error pausing event: {0}", response.Message); + Debug.Console(1, this, "Error pausing event: {0}", response.Message); } } @@ -292,7 +301,7 @@ private void ResumeRunningEvent() { if (_runningEvent == null) { - Debug.Console(0, this, "No running event"); + Debug.Console(1, this, "No running event"); return; } @@ -302,7 +311,7 @@ private void ResumeRunningEvent() if (response == null) { - Debug.Console(0, this, "Unable to resume event"); + Debug.Console(1, this, "Unable to resume event"); _monitor.SetOnlineStatus(false); @@ -311,7 +320,7 @@ private void ResumeRunningEvent() if (!response.Status.Equals("ok", StringComparison.InvariantCultureIgnoreCase)) { - Debug.Console(0, this, "Error resuming event: {0}", response.Message); + Debug.Console(1, this, "Error resuming event: {0}", response.Message); } } @@ -319,7 +328,7 @@ private void StopRunningEvent() { if (_runningEvent == null) { - Debug.Console(0, this, "No running event"); + Debug.Console(1, this, "No running event"); return; } @@ -329,7 +338,7 @@ private void StopRunningEvent() if (response == null) { - Debug.Console(0, this, "Unable to stop event"); + Debug.Console(1, this, "Unable to stop event"); _monitor.SetOnlineStatus(false); @@ -338,10 +347,10 @@ private void StopRunningEvent() if (!response.Status.Equals("ok", StringComparison.InvariantCultureIgnoreCase)) { - Debug.Console(0, this, "Error stopping event: {0}", response.Message); + Debug.Console(1, this, "Error stopping event: {0}", response.Message); } - StopEventStatusTimer(); + //StopEventStatusTimer(); GetRunningEventStatus(); @@ -358,7 +367,7 @@ private void StartEvent() if (string.IsNullOrEmpty(id)) { - Debug.Console(0, this, "No scheduled event to start"); + Debug.Console(1, this, "No scheduled event to start"); return; } @@ -368,7 +377,7 @@ private void StartEvent() if (response == null) { - Debug.Console(0, this, "Unable to start event"); + Debug.Console(1, this, "Unable to start event"); _monitor.SetOnlineStatus(false); @@ -377,13 +386,13 @@ private void StartEvent() if (!response.Status.Equals("ok", StringComparison.InvariantCultureIgnoreCase)) { - Debug.Console(0, this, "Error starting event: {0}", response.Message); + Debug.Console(1, this, "Error starting event: {0}", response.Message); return; } GetRunningEvent(); - StartEventStatusTimer(); + //StartEventStatusTimer(); } private void ExtendRunningEvent() @@ -399,7 +408,7 @@ private void ExtendRunningEvent() if (response == null) { - Debug.Console(0, this, "Unable to extend event"); + Debug.Console(1, this, "Unable to extend event"); _monitor.SetOnlineStatus(false); @@ -408,7 +417,7 @@ private void ExtendRunningEvent() if (!response.Status.Equals("ok", StringComparison.InvariantCultureIgnoreCase)) { - Debug.Console(0, this, "Error extending event: {0}", response.Message); + Debug.Console(1, this, "Error extending event: {0}", response.Message); } } @@ -424,7 +433,7 @@ private void GetScheduledEvents() if (response == null) { - Debug.Console(0, this, "Unable to get scheduled events"); + Debug.Console(1, this, "Unable to get scheduled events"); _scheduledEvents = new List(); @@ -475,7 +484,7 @@ private void GetRunningEvent() { // Current event could be either running or paused - Debug.Console(2, this, "Getting Running Events"); + Debug.Console(1, this, "Getting Running Events"); var runningEventPath = string.Format("/schedule/events/?status=running"); @@ -485,19 +494,19 @@ private void GetRunningEvent() if (response == null) { - Debug.Console(0, this, "Unable to get running event"); + Debug.Console(1, this, "Unable to get running event"); } if (response != null && response.Result.Count > 0) { _runningEvent = response.Result[0]; - Debug.Console(2, this, "Running Event: {0} | {1} | {2} | {3} | ", _runningEvent.Id, + Debug.Console(1, this, "Running Event: {0} | {1} | {2} | {3} | ", _runningEvent.Id, _runningEvent.Title, _runningEvent.Start, _runningEvent.Finish); UpdateFeedbacks(); - StartEventStatusTimer(); + //StartEventStatusTimer(); return; } @@ -505,11 +514,11 @@ private void GetRunningEvent() if (response == null) { - Debug.Console(0, this, "Unable to get paused event"); + Debug.Console(1, this, "Unable to get paused event"); _runningEvent = null; UpdateFeedbacks(); - StopEventStatusTimer(); + //StopEventStatusTimer(); return; } @@ -520,14 +529,14 @@ private void GetRunningEvent() if (_runningEvent != null) { - StartEventStatusTimer(); + //StartEventStatusTimer(); - Debug.Console(2, this, "Running Event: {0} | {1} | {2} | {3} | ", _runningEvent.Id, + Debug.Console(1, this, "Running Event: {0} | {1} | {2} | {3} | ", _runningEvent.Id, _runningEvent.Title, _runningEvent.Start, _runningEvent.Finish); } else { - StopEventStatusTimer(); + //StopEventStatusTimer(); } } @@ -545,13 +554,14 @@ private void GetRunningEventStatus() if (response == null) { - Debug.Console(0, this, "Unable to get running event status"); + Debug.Console(1, this, "Unable to get running event status"); return; } _runningEvent.Status = response.Result; _runningEventRunningFeedback.FireUpdate(); + _runningEventPausedFeedback.FireUpdate(); } private void UpdateFeedbacks() @@ -564,6 +574,7 @@ private void UpdateFeedbacks() _runningEventTimeRemainingFeedback.FireUpdate(); _runningEventRunningFeedback.FireUpdate(); + _runningEventPausedFeedback.FireUpdate(); _nextEventExistsFeedback.FireUpdate(); for (var i = 0; i < _scheduledRecordings.Count; i++) diff --git a/src/EpiphanPearl/EpiphanPearlSecureClient.cs b/src/EpiphanPearl/EpiphanPearlSecureClient.cs index b58fdea..b534e16 100644 --- a/src/EpiphanPearl/EpiphanPearlSecureClient.cs +++ b/src/EpiphanPearl/EpiphanPearlSecureClient.cs @@ -45,12 +45,12 @@ public T Get(string path) where T: class } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[T Get] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[T Get] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; @@ -77,12 +77,12 @@ public TResponse Post(string path, TBody body) where TBody : c } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; @@ -109,12 +109,12 @@ public TResponse Post(string path) } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[TResponse Post] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; @@ -136,21 +136,22 @@ private string SendRequest(HttpsClientRequest request) { try { + //Debug.Console(0, "Request to {0): {1}", request.Url, request.ContentString); var response = _client.Dispatch(request); - Debug.Console(0, "Response from request to {0}: {1} {2}", request.Url, response.Code, - response.ContentString); + //Debug.Console(0, "Response from request to {0}: {1} {2}", request.Url, response.Code, + //response.ContentString); return response.ContentString; } catch (Exception ex) { - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.Message); + Debug.Console(0, "[SendRequest] Exception sending to {0}: {1}", request.Url, ex.Message); Debug.Console(2, "Stack Trace: {0}", ex.StackTrace); if (ex.InnerException == null) return null; - Debug.Console(0, "Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); + Debug.Console(0, "[SendRequest] Exception sending to {0}: {1}", request.Url, ex.InnerException.Message); Debug.Console(2, "Stack Trace: {0}", ex.InnerException.StackTrace); return null; diff --git a/src/EpiphanPearl/Event.cs b/src/EpiphanPearl/Event.cs index 09c28c6..6fc83fa 100644 --- a/src/EpiphanPearl/Event.cs +++ b/src/EpiphanPearl/Event.cs @@ -39,8 +39,30 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - if (reader.Value == null) { return null; } - return _epoch.AddSeconds((long)reader.Value); + if (reader.Value == null) + { + return null; + } + + try + { + long seconds = long.Parse(reader.Value.ToString()); + return _epoch.AddSeconds(seconds); + } + catch (FormatException) + { + // Handle the case when the value is not a valid long + // You can choose to return a default value, throw a custom exception, or log an error + // For example: + return _epoch; + } + catch (OverflowException) + { + // Handle the case when the value is too large to fit into a long + // You can choose to return a default value, throw a custom exception, or log an error + // For example: + return DateTime.MaxValue; + } } } } \ No newline at end of file