From 279acb42757a84e35e3eeaf6f2ca8a74cf76c6f1 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos <6349682+vaind@users.noreply.github.com> Date: Mon, 16 May 2022 09:14:25 +0200 Subject: [PATCH] fix: collect main thread data synchronously during init (#744) * fix: collect main thread data synchronously during init * chore: update changelog --- CHANGELOG.md | 1 + src/Sentry.Unity/SentryMonoBehaviour.cs | 11 ++-- .../UnityEventProcessorTests.cs | 60 +++++++++---------- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc5480f2c..dafbc925a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Linux native crash support ([#734](https://github.com/getsentry/sentry-unity/pull/734)) +- Collect context information synchronously during init to capture it for very early events ([#744](https://github.com/getsentry/sentry-unity/pull/744)) ## 0.16.0 diff --git a/src/Sentry.Unity/SentryMonoBehaviour.cs b/src/Sentry.Unity/SentryMonoBehaviour.cs index 594c20579..901347e6a 100644 --- a/src/Sentry.Unity/SentryMonoBehaviour.cs +++ b/src/Sentry.Unity/SentryMonoBehaviour.cs @@ -138,13 +138,15 @@ internal ISentrySystemInfo SentrySystemInfo set => _sentrySystemInfo = value; } - private void Start() - => StartCoroutine(CollectData()); + // Note: Awake is called only once and synchronously while the object is built. + // We want to do it this way instead of a StartCoroutine() so that we have the context info ASAP. + private void Awake() => CollectData(); - internal IEnumerator CollectData() + internal void CollectData() { + // Note: Awake() runs on the main thread. The following code just reads a couple of variables so there's no + // delay on the UI and we're safe to do it on the main thread. MainThreadData.MainThreadId = SentrySystemInfo.MainThreadId; - yield return null; MainThreadData.ProcessorCount = SentrySystemInfo.ProcessorCount; MainThreadData.DeviceType = SentrySystemInfo.DeviceType; MainThreadData.OperatingSystem = SentrySystemInfo.OperatingSystem; @@ -154,7 +156,6 @@ internal IEnumerator CollectData() MainThreadData.DeviceUniqueIdentifier = SentrySystemInfo.DeviceUniqueIdentifier; MainThreadData.DeviceModel = SentrySystemInfo.DeviceModel; MainThreadData.SystemMemorySize = SentrySystemInfo.SystemMemorySize; - yield return null; MainThreadData.GraphicsDeviceId = SentrySystemInfo.GraphicsDeviceId; MainThreadData.GraphicsDeviceName = SentrySystemInfo.GraphicsDeviceName; MainThreadData.GraphicsDeviceVendorId = SentrySystemInfo.GraphicsDeviceVendorId; diff --git a/test/Sentry.Unity.Tests/UnityEventProcessorTests.cs b/test/Sentry.Unity.Tests/UnityEventProcessorTests.cs index 62f617b22..32f2816b4 100644 --- a/test/Sentry.Unity.Tests/UnityEventProcessorTests.cs +++ b/test/Sentry.Unity.Tests/UnityEventProcessorTests.cs @@ -85,8 +85,8 @@ public void SentrySdkCaptureEvent_OnNotUIThread_Succeeds() Assert.NotZero(_testLogger.Logs.Count(log => log.logLevel <= SentryLevel.Info)); } - [UnityTest] - public IEnumerator SentrySdkCaptureEvent_OnNotUIThreadThenUIThreadThenNotUIThread_Cached() + [Test] + public void SentrySdkCaptureEvent_OnNotUIThreadThenUIThreadThenNotUIThread_Cached() { // arrange _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo @@ -113,7 +113,7 @@ public IEnumerator SentrySdkCaptureEvent_OnNotUIThreadThenUIThreadThenNotUIThrea options.AddEventProcessor(new UnityEventProcessor(options, _sentryMonoBehaviour, _testApplication)); SentryUnity.Init(options); - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); // act & assert var nonUiThreadEventDataNotCached = NonUiThread(); @@ -275,8 +275,8 @@ public void Process_ServerName_IsNull() Assert.IsNull(sentryEvent.ServerName); } - [UnityTest] - public IEnumerator Process_DeviceUniqueIdentifierWithSendDefaultPii_IsNotNull() + [Test] + public void Process_DeviceUniqueIdentifierWithSendDefaultPii_IsNotNull() { // arrange var sentryOptions = new SentryOptions { SendDefaultPii = true }; @@ -284,15 +284,15 @@ public IEnumerator Process_DeviceUniqueIdentifierWithSendDefaultPii_IsNotNull() var sentryEvent = new SentryEvent(); // act - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); // assert Assert.IsNotNull(sentryEvent.Contexts.Device.DeviceUniqueIdentifier); } - [UnityTest] - public IEnumerator Process_AppProtocol_Assigned() + [Test] + public void Process_AppProtocol_Assigned() { // arrange _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo @@ -303,15 +303,15 @@ public IEnumerator Process_AppProtocol_Assigned() var sentryEvent = new SentryEvent(); // act - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); unityEventProcessor.Process(sentryEvent); // assert Assert.IsNotNull(sentryEvent.Contexts.App.StartTime); } - [UnityTest] - public IEnumerator Process_Tags_Set() + [Test] + public void Process_Tags_Set() { // arrange _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo @@ -327,7 +327,7 @@ public IEnumerator Process_Tags_Set() var sentryEvent = new SentryEvent(); // act - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); unityEventProcessor.Process(sentryEvent); // assert @@ -357,8 +357,8 @@ public IEnumerator Process_Tags_Set() Assert.AreEqual("true", isMainThread.Value); } - [UnityTest] - public IEnumerator Process_OperatingSystemProtocol_Assigned() + [Test] + public void Process_OperatingSystemProtocol_Assigned() { // arrange _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo { OperatingSystem = "Windows" }; @@ -367,15 +367,15 @@ public IEnumerator Process_OperatingSystemProtocol_Assigned() // act // SentryInitialization always called - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); // assert Assert.AreEqual(_sentryMonoBehaviour.SentrySystemInfo.OperatingSystem, sentryEvent.Contexts.OperatingSystem.RawDescription); } - [UnityTest] - public IEnumerator Process_DeviceProtocol_Assigned() + [Test] + public void Process_DeviceProtocol_Assigned() { const long toByte = 1048576L; // in `UnityEventProcessor.PopulateDevice` _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo @@ -391,7 +391,7 @@ public IEnumerator Process_DeviceProtocol_Assigned() var sut = new UnityEventProcessor(_sentryOptions, _sentryMonoBehaviour, _testApplication); var sentryEvent = new SentryEvent(); - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); Assert.AreEqual(_sentryMonoBehaviour.SentrySystemInfo.ProcessorCount, sentryEvent.Contexts.Device.ProcessorCount); @@ -403,8 +403,8 @@ public IEnumerator Process_DeviceProtocol_Assigned() Assert.AreEqual(_sentryMonoBehaviour.SentrySystemInfo.SystemMemorySize * toByte, sentryEvent.Contexts.Device.MemorySize); } - [UnityTest] - public IEnumerator Process_UnityProtocol_Assigned() + [Test] + public void Process_UnityProtocol_Assigned() { _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo { @@ -418,7 +418,7 @@ public IEnumerator Process_UnityProtocol_Assigned() var sentryEvent = new SentryEvent(); // act - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); var unityProtocol = (Unity.Protocol.Unity)sentryEvent.Contexts.GetOrAdd(Unity.Protocol.Unity.Type, _ => new Unity.Protocol.Unity()); @@ -428,8 +428,8 @@ public IEnumerator Process_UnityProtocol_Assigned() Assert.AreEqual(_sentryMonoBehaviour.SentrySystemInfo.RenderingThreadingMode!.Value, unityProtocol.RenderingThreadingMode); } - [UnityTest] - public IEnumerator Process_GpuProtocol_Assigned() + [Test] + public void Process_GpuProtocol_Assigned() { _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo { @@ -453,7 +453,7 @@ public IEnumerator Process_GpuProtocol_Assigned() // act // SentryInitialization always called - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); Assert.AreEqual(_sentryMonoBehaviour.SentrySystemInfo.GraphicsDeviceId, sentryEvent.Contexts.Gpu.Id); @@ -472,8 +472,8 @@ public IEnumerator Process_GpuProtocol_Assigned() Assert.AreEqual(_sentryMonoBehaviour.SentrySystemInfo.SupportsGeometryShaders, sentryEvent.Contexts.Gpu.SupportsGeometryShaders); } - [UnityTest] - public IEnumerator Process_GpuProtocolGraphicsShaderLevel_Assigned( + [Test] + public void Process_GpuProtocolGraphicsShaderLevel_Assigned( [ValueSource(nameof(ShaderLevels))] (int, string) shaderValue) { var (shaderLevel, shaderDescription) = shaderValue; @@ -488,7 +488,7 @@ public IEnumerator Process_GpuProtocolGraphicsShaderLevel_Assigned( // act // SentryInitialization always called - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); Assert.AreEqual(shaderDescription, sentryEvent.Contexts.Gpu.GraphicsShaderLevel); @@ -507,8 +507,8 @@ private static readonly (int shaderLevel, string shaderDescription)[] ShaderLeve (21, "21") }; - [UnityTest] - public IEnumerator Process_GpuProtocolGraphicsShaderLevelMinusOne_Ignored() + [Test] + public void Process_GpuProtocolGraphicsShaderLevelMinusOne_Ignored() { _sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo { @@ -520,7 +520,7 @@ public IEnumerator Process_GpuProtocolGraphicsShaderLevelMinusOne_Ignored() // act // SentryInitialization always called - yield return _sentryMonoBehaviour.CollectData(); + _sentryMonoBehaviour.CollectData(); sut.Process(sentryEvent); Assert.IsNull(sentryEvent.Contexts.Gpu.GraphicsShaderLevel);