From f9d9071b149d0762b0a5c81419f86fe4e35f7f1c Mon Sep 17 00:00:00 2001 From: CoderGamester Date: Sun, 2 Feb 2025 01:16:10 +0000 Subject: [PATCH 1/6] Update the Event Flushing Mechanism to avoid losing events due to network issues or game being closed - Add the option to save events to disk if they failed to be sent when the game loses focus on the device screen. --- Runtime/Aptabase.cs | 2 +- Runtime/Dispatcher/Dispatcher.cs | 15 ++++++++++++--- Runtime/Dispatcher/IDispatcher.cs | 4 +++- Runtime/Dispatcher/WebGLDispatcher.cs | 13 +++++++++++-- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Runtime/Aptabase.cs b/Runtime/Aptabase.cs index fc9e39d..f763f2e 100644 --- a/Runtime/Aptabase.cs +++ b/Runtime/Aptabase.cs @@ -103,7 +103,7 @@ public static void OnApplicationFocus(bool hasFocus) } else { - Flush(); + _dispatcher.FlushOrSaveToDisk(); StopPolling(); } } diff --git a/Runtime/Dispatcher/Dispatcher.cs b/Runtime/Dispatcher/Dispatcher.cs index c38ed68..750be6a 100644 --- a/Runtime/Dispatcher/Dispatcher.cs +++ b/Runtime/Dispatcher/Dispatcher.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using AptabaseSDK.TinyJson; using UnityEngine; @@ -8,6 +9,7 @@ namespace AptabaseSDK public class Dispatcher: IDispatcher { private const string EVENTS_ENDPOINT = "/api/v0/events"; + private const string APTDABASE_KEY = "AptabaseKey"; private const int MAX_BATCH_SIZE = 25; @@ -22,7 +24,7 @@ public class Dispatcher: IDispatcher public Dispatcher(string appKey, string baseURL, EnvironmentInfo env) { //create event queue - _events = new Queue(); + _events = new Queue(PlayerPrefs.GetString("AptabaseEvents").FromJson>() ?? new List()); //web request setup information _apiURL = $"{baseURL}{EVENTS_ENDPOINT}"; @@ -42,7 +44,7 @@ private void Enqueue(List data) _events.Enqueue(eventData); } - public async void Flush() + public async Task Flush() { if (_flushInProgress || _events.Count <= 0) return; @@ -75,7 +77,14 @@ public async void Flush() _flushInProgress = false; } - + + public async void FlushOrSaveToDisk() + { + await Flush(); + + PlayerPrefs.SetString(APTDABASE_KEY, _events.ToList().ToJson()); + } + private static async Task SendEvents(List events) { var webRequest = _webRequestHelper.CreateWebRequest(_apiURL, _appKey, _environment, events.ToJson()); diff --git a/Runtime/Dispatcher/IDispatcher.cs b/Runtime/Dispatcher/IDispatcher.cs index c7c34bc..e02eea0 100644 --- a/Runtime/Dispatcher/IDispatcher.cs +++ b/Runtime/Dispatcher/IDispatcher.cs @@ -4,6 +4,8 @@ public interface IDispatcher { public void Enqueue(Event data); - public void Flush(); + public Task Flush(); + + public void FlushOrSaveToDisk(); } } \ No newline at end of file diff --git a/Runtime/Dispatcher/WebGLDispatcher.cs b/Runtime/Dispatcher/WebGLDispatcher.cs index 020b830..a64487f 100644 --- a/Runtime/Dispatcher/WebGLDispatcher.cs +++ b/Runtime/Dispatcher/WebGLDispatcher.cs @@ -1,12 +1,15 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using AptabaseSDK.TinyJson; +using UnityEngine; namespace AptabaseSDK { public class WebGLDispatcher: IDispatcher { private const string EVENT_ENDPOINT = "/api/v0/event"; + private const string APTDABASE_KEY = "AptabaseKey"; private static string _apiURL; private static WebRequestHelper _webRequestHelper; @@ -31,7 +34,6 @@ public WebGLDispatcher(string appKey, string baseURL, EnvironmentInfo env) public void Enqueue(Event data) { _events.Enqueue(data); - Flush(); } private void Enqueue(List data) @@ -40,7 +42,7 @@ private void Enqueue(List data) _events.Enqueue(eventData); } - public async void Flush() + public async Task Flush() { if (_flushInProgress || _events.Count <= 0) return; @@ -69,6 +71,13 @@ public async void Flush() _flushInProgress = false; } + + public async void FlushOrSaveToDisk() + { + await Flush(); + + PlayerPrefs.SetString(APTDABASE_KEY, _events.ToList().ToJson()); + } private static async Task SendEvent(Event eventData) { From fb19f7d0a9d0676b14b3a8265579576dc499d9eb Mon Sep 17 00:00:00 2001 From: Coder Gamester Date: Mon, 3 Feb 2025 13:24:54 +0000 Subject: [PATCH 2/6] Fix IDispatcher interface declaration to contain to reflect the Task behaviour of Flush methods --- Runtime/Dispatcher/Dispatcher.cs | 2 +- Runtime/Dispatcher/IDispatcher.cs | 8 +++++--- Runtime/Dispatcher/WebGLDispatcher.cs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Runtime/Dispatcher/Dispatcher.cs b/Runtime/Dispatcher/Dispatcher.cs index 750be6a..4ea5e64 100644 --- a/Runtime/Dispatcher/Dispatcher.cs +++ b/Runtime/Dispatcher/Dispatcher.cs @@ -78,7 +78,7 @@ public async Task Flush() _flushInProgress = false; } - public async void FlushOrSaveToDisk() + public async Task FlushOrSaveToDisk() { await Flush(); diff --git a/Runtime/Dispatcher/IDispatcher.cs b/Runtime/Dispatcher/IDispatcher.cs index e02eea0..d604147 100644 --- a/Runtime/Dispatcher/IDispatcher.cs +++ b/Runtime/Dispatcher/IDispatcher.cs @@ -1,11 +1,13 @@ +using System.Threading.Tasks; + namespace AptabaseSDK { public interface IDispatcher { - public void Enqueue(Event data); + void Enqueue(Event data); - public Task Flush(); + Task Flush(); - public void FlushOrSaveToDisk(); + Task FlushOrSaveToDisk(); } } \ No newline at end of file diff --git a/Runtime/Dispatcher/WebGLDispatcher.cs b/Runtime/Dispatcher/WebGLDispatcher.cs index a64487f..e45ae1a 100644 --- a/Runtime/Dispatcher/WebGLDispatcher.cs +++ b/Runtime/Dispatcher/WebGLDispatcher.cs @@ -72,7 +72,7 @@ public async Task Flush() _flushInProgress = false; } - public async void FlushOrSaveToDisk() + public async Task FlushOrSaveToDisk() { await Flush(); From 728fa218a94ee14872c40a61dcd5b7a50e8e024b Mon Sep 17 00:00:00 2001 From: Coder Gamester Date: Sat, 8 Feb 2025 11:53:20 +0000 Subject: [PATCH 3/6] Disable sending events if application is offline --- Runtime/Dispatcher/Dispatcher.cs | 2 ++ Runtime/Dispatcher/WebGLDispatcher.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Runtime/Dispatcher/Dispatcher.cs b/Runtime/Dispatcher/Dispatcher.cs index 4ea5e64..01693f4 100644 --- a/Runtime/Dispatcher/Dispatcher.cs +++ b/Runtime/Dispatcher/Dispatcher.cs @@ -87,6 +87,8 @@ public async Task FlushOrSaveToDisk() private static async Task SendEvents(List events) { + if(Application.internetReachability == NetworkReachability.NotReachable) return false; + var webRequest = _webRequestHelper.CreateWebRequest(_apiURL, _appKey, _environment, events.ToJson()); var result = await _webRequestHelper.SendWebRequestAsync(webRequest); return result; diff --git a/Runtime/Dispatcher/WebGLDispatcher.cs b/Runtime/Dispatcher/WebGLDispatcher.cs index e45ae1a..6cd7992 100644 --- a/Runtime/Dispatcher/WebGLDispatcher.cs +++ b/Runtime/Dispatcher/WebGLDispatcher.cs @@ -81,6 +81,8 @@ public async Task FlushOrSaveToDisk() private static async Task SendEvent(Event eventData) { + if(Application.internetReachability == NetworkReachability.NotReachable) return false; + var webRequest = _webRequestHelper.CreateWebRequest(_apiURL, _appKey, _environment, eventData.ToJson()); var result = await _webRequestHelper.SendWebRequestAsync(webRequest); return result; From 6877da2dad2c74dd4e57c8108676690b12bdeec0 Mon Sep 17 00:00:00 2001 From: Coder Gamester Date: Sat, 8 Feb 2025 20:13:06 +0000 Subject: [PATCH 4/6] Fix the cleanup from disk after getting the events from cache --- Runtime/Dispatcher/Dispatcher.cs | 6 +++++- Runtime/Dispatcher/WebGLDispatcher.cs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Runtime/Dispatcher/Dispatcher.cs b/Runtime/Dispatcher/Dispatcher.cs index 01693f4..8147225 100644 --- a/Runtime/Dispatcher/Dispatcher.cs +++ b/Runtime/Dispatcher/Dispatcher.cs @@ -23,14 +23,18 @@ public class Dispatcher: IDispatcher public Dispatcher(string appKey, string baseURL, EnvironmentInfo env) { + var cacheEvents = PlayerPrefs.GetString(APTDABASE_KEY).FromJson>(); + //create event queue - _events = new Queue(PlayerPrefs.GetString("AptabaseEvents").FromJson>() ?? new List()); + _events = new Queue(cacheEvents ?? new List()); //web request setup information _apiURL = $"{baseURL}{EVENTS_ENDPOINT}"; _appKey = appKey; _environment = env; _webRequestHelper = new WebRequestHelper(); + + PlayerPrefs.DeleteKey(APTDABASE_KEY); } public void Enqueue(Event data) diff --git a/Runtime/Dispatcher/WebGLDispatcher.cs b/Runtime/Dispatcher/WebGLDispatcher.cs index 6cd7992..54c07dc 100644 --- a/Runtime/Dispatcher/WebGLDispatcher.cs +++ b/Runtime/Dispatcher/WebGLDispatcher.cs @@ -21,14 +21,18 @@ public class WebGLDispatcher: IDispatcher public WebGLDispatcher(string appKey, string baseURL, EnvironmentInfo env) { + var cacheEvents = PlayerPrefs.GetString(APTDABASE_KEY).FromJson>(); + //create event queue - _events = new Queue(); + _events = new Queue(cacheEvents ?? new List()); //web request setup information _apiURL = $"{baseURL}{EVENT_ENDPOINT}"; _appKey = appKey; _environment = env; _webRequestHelper = new WebRequestHelper(); + + PlayerPrefs.DeleteKey(APTDABASE_KEY); } public void Enqueue(Event data) From 502ddb11a5a9a6dc0b584622365d6345e500c56f Mon Sep 17 00:00:00 2001 From: Coder Gamester Date: Sat, 8 Feb 2025 20:43:13 +0000 Subject: [PATCH 5/6] Fix type of PlayerPref key --- Runtime/Dispatcher/Dispatcher.cs | 8 ++++---- Runtime/Dispatcher/WebGLDispatcher.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Runtime/Dispatcher/Dispatcher.cs b/Runtime/Dispatcher/Dispatcher.cs index 8147225..e5f4e51 100644 --- a/Runtime/Dispatcher/Dispatcher.cs +++ b/Runtime/Dispatcher/Dispatcher.cs @@ -9,7 +9,7 @@ namespace AptabaseSDK public class Dispatcher: IDispatcher { private const string EVENTS_ENDPOINT = "/api/v0/events"; - private const string APTDABASE_KEY = "AptabaseKey"; + private const string APTABASE_KEY = "aptabase_key"; private const int MAX_BATCH_SIZE = 25; @@ -23,7 +23,7 @@ public class Dispatcher: IDispatcher public Dispatcher(string appKey, string baseURL, EnvironmentInfo env) { - var cacheEvents = PlayerPrefs.GetString(APTDABASE_KEY).FromJson>(); + var cacheEvents = PlayerPrefs.GetString(APTABASE_KEY).FromJson>(); //create event queue _events = new Queue(cacheEvents ?? new List()); @@ -34,7 +34,7 @@ public Dispatcher(string appKey, string baseURL, EnvironmentInfo env) _environment = env; _webRequestHelper = new WebRequestHelper(); - PlayerPrefs.DeleteKey(APTDABASE_KEY); + PlayerPrefs.DeleteKey(APTABASE_KEY); } public void Enqueue(Event data) @@ -86,7 +86,7 @@ public async Task FlushOrSaveToDisk() { await Flush(); - PlayerPrefs.SetString(APTDABASE_KEY, _events.ToList().ToJson()); + PlayerPrefs.SetString(APTABASE_KEY, _events.ToList().ToJson()); } private static async Task SendEvents(List events) diff --git a/Runtime/Dispatcher/WebGLDispatcher.cs b/Runtime/Dispatcher/WebGLDispatcher.cs index 54c07dc..6bf3010 100644 --- a/Runtime/Dispatcher/WebGLDispatcher.cs +++ b/Runtime/Dispatcher/WebGLDispatcher.cs @@ -9,7 +9,7 @@ namespace AptabaseSDK public class WebGLDispatcher: IDispatcher { private const string EVENT_ENDPOINT = "/api/v0/event"; - private const string APTDABASE_KEY = "AptabaseKey"; + private const string APTABASE_KEY = "aptabase_key"; private static string _apiURL; private static WebRequestHelper _webRequestHelper; @@ -21,7 +21,7 @@ public class WebGLDispatcher: IDispatcher public WebGLDispatcher(string appKey, string baseURL, EnvironmentInfo env) { - var cacheEvents = PlayerPrefs.GetString(APTDABASE_KEY).FromJson>(); + var cacheEvents = PlayerPrefs.GetString(APTABASE_KEY).FromJson>(); //create event queue _events = new Queue(cacheEvents ?? new List()); @@ -32,7 +32,7 @@ public WebGLDispatcher(string appKey, string baseURL, EnvironmentInfo env) _environment = env; _webRequestHelper = new WebRequestHelper(); - PlayerPrefs.DeleteKey(APTDABASE_KEY); + PlayerPrefs.DeleteKey(APTABASE_KEY); } public void Enqueue(Event data) @@ -80,7 +80,7 @@ public async Task FlushOrSaveToDisk() { await Flush(); - PlayerPrefs.SetString(APTDABASE_KEY, _events.ToList().ToJson()); + PlayerPrefs.SetString(APTABASE_KEY, _events.ToList().ToJson()); } private static async Task SendEvent(Event eventData) From 72c8ec9c1834b56d90273c5fce3649f089f3a29a Mon Sep 17 00:00:00 2001 From: Coder Gamester Date: Sun, 9 Feb 2025 21:58:46 +0000 Subject: [PATCH 6/6] Fix bug when using Aptabase Unity SDK for the first time in the game running or without saved cache events --- Runtime/Dispatcher/Dispatcher.cs | 5 +++-- Runtime/Dispatcher/WebGLDispatcher.cs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Runtime/Dispatcher/Dispatcher.cs b/Runtime/Dispatcher/Dispatcher.cs index e5f4e51..91c0a69 100644 --- a/Runtime/Dispatcher/Dispatcher.cs +++ b/Runtime/Dispatcher/Dispatcher.cs @@ -23,10 +23,11 @@ public class Dispatcher: IDispatcher public Dispatcher(string appKey, string baseURL, EnvironmentInfo env) { - var cacheEvents = PlayerPrefs.GetString(APTABASE_KEY).FromJson>(); + var cachedEventsJson = PlayerPrefs.GetString(APTABASE_KEY); + var cacheEvents = string.IsNullOrEmpty(cachedEventsJson) ? new List() : cachedEventsJson.FromJson>(); //create event queue - _events = new Queue(cacheEvents ?? new List()); + _events = new Queue(cacheEvents); //web request setup information _apiURL = $"{baseURL}{EVENTS_ENDPOINT}"; diff --git a/Runtime/Dispatcher/WebGLDispatcher.cs b/Runtime/Dispatcher/WebGLDispatcher.cs index 6bf3010..d53ab2f 100644 --- a/Runtime/Dispatcher/WebGLDispatcher.cs +++ b/Runtime/Dispatcher/WebGLDispatcher.cs @@ -21,10 +21,11 @@ public class WebGLDispatcher: IDispatcher public WebGLDispatcher(string appKey, string baseURL, EnvironmentInfo env) { - var cacheEvents = PlayerPrefs.GetString(APTABASE_KEY).FromJson>(); + var cachedEventsJson = PlayerPrefs.GetString(APTABASE_KEY); + var cacheEvents = string.IsNullOrEmpty(cachedEventsJson) ? new List() : cachedEventsJson.FromJson>(); //create event queue - _events = new Queue(cacheEvents ?? new List()); + _events = new Queue(cacheEvents); //web request setup information _apiURL = $"{baseURL}{EVENT_ENDPOINT}";