Skip to content

Commit 49cc72a

Browse files
committed
Simplify logic to record app startup traces
1 parent dc37ab5 commit 49cc72a

File tree

1 file changed

+62
-74
lines changed

1 file changed

+62
-74
lines changed

embrace-android-features/src/main/kotlin/io/embrace/android/embracesdk/internal/capture/startup/AppStartupTraceEmitter.kt

Lines changed: 62 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import io.embrace.android.embracesdk.spans.ErrorCode
1616
import io.opentelemetry.sdk.common.Clock
1717
import java.util.concurrent.ConcurrentHashMap
1818
import java.util.concurrent.ConcurrentLinkedQueue
19-
import java.util.concurrent.atomic.AtomicBoolean
2019
import java.util.concurrent.atomic.AtomicReference
2120

2221
/**
@@ -51,6 +50,8 @@ internal class AppStartupTraceEmitter(
5150
private val processCreatedMs: Long?
5251
private val additionalTrackedIntervals = ConcurrentLinkedQueue<TrackedInterval>()
5352
private val customAttributes: MutableMap<String, String> = ConcurrentHashMap()
53+
private val endWithFrameDraw: Boolean = startupHasRenderEvent(versionChecker)
54+
private val appStartupRootSpan = AtomicReference<PersistableEmbraceSpan?>(null)
5455

5556
init {
5657
val timestampAtDeviceStart = nowMs() - clock.nanoTime().nanosToMillis()
@@ -97,12 +98,10 @@ internal class AppStartupTraceEmitter(
9798
private var firstFrameRenderedMs: Long? = null
9899

99100
@Volatile
100-
private var recordColdStart = true
101+
private var dataCollectionComplete = false
101102

102-
private val appStartupRootSpan = AtomicReference<PersistableEmbraceSpan?>(null)
103-
private val startupRecorded = AtomicBoolean(false)
104-
private val dataCollectionComplete = AtomicBoolean(false)
105-
private val endWithFrameDraw: Boolean = startupHasRenderEvent(versionChecker)
103+
@Volatile
104+
private var recordColdStart = true
106105

107106
override fun applicationInitStart(timestampMs: Long?) {
108107
applicationInitStartMs = timestampMs ?: nowMs()
@@ -202,22 +201,18 @@ internal class AppStartupTraceEmitter(
202201
* Called when app startup is considered complete, i.e. the data can be used and any additional updates can be ignored
203202
*/
204203
private fun dataCollectionComplete(callback: (() -> Unit)?) {
205-
if (!dataCollectionComplete.get()) {
206-
synchronized(dataCollectionComplete) {
207-
if (!dataCollectionComplete.get()) {
208-
backgroundWorker.submit {
209-
recordStartup()
210-
if (!startupRecorded.get()) {
211-
logger.trackInternalError(
212-
type = InternalErrorType.APP_LAUNCH_TRACE_FAIL,
213-
throwable = IllegalStateException("App startup trace recording attempted but did not succeed")
214-
)
215-
}
216-
}
217-
callback?.invoke()
218-
dataCollectionComplete.set(true)
204+
if (!dataCollectionComplete) {
205+
backgroundWorker.submit {
206+
recordStartup()
207+
if (appStartupRootSpan.get()?.isRecording != false) {
208+
logger.trackInternalError(
209+
type = InternalErrorType.APP_LAUNCH_TRACE_FAIL,
210+
throwable = IllegalStateException("App startup trace recording attempted but did not succeed")
211+
)
219212
}
220213
}
214+
callback?.invoke()
215+
dataCollectionComplete = true
221216
}
222217
}
223218

@@ -296,7 +291,6 @@ internal class AppStartupTraceEmitter(
296291
} while (additionalTrackedIntervals.isNotEmpty())
297292
}
298293

299-
@Suppress("CyclomaticComplexMethod", "ComplexMethod")
300294
private fun recordTtid(
301295
applicationInitEndMs: Long?,
302296
sdkInitStartMs: Long?,
@@ -305,69 +299,63 @@ internal class AppStartupTraceEmitter(
305299
activityInitStartMs: Long?,
306300
activityInitEndMs: Long?,
307301
traceEndTimeMs: Long,
308-
): EmbraceSpan? {
309-
return if (!startupRecorded.get()) {
310-
appStartupRootSpan.get()?.apply {
311-
addTraceMetadata()
312-
313-
if (stop(endTimeMs = traceEndTimeMs)) {
314-
startupRecorded.set(true)
315-
}
302+
) {
303+
appStartupRootSpan.get()?.takeIf { it.isRecording }?.apply {
304+
addTraceMetadata()
316305

317-
getStartTimeMs()?.let { traceStartTimeMs ->
318-
if (applicationInitEndMs != null) {
319-
spanService.recordCompletedSpan(
320-
name = "process-init",
321-
parent = this,
322-
startTimeMs = traceStartTimeMs,
323-
endTimeMs = applicationInitEndMs,
324-
)
325-
}
326-
}
306+
stop(endTimeMs = traceEndTimeMs)
327307

328-
if (sdkInitStartMs != null && sdkInitEndMs != null) {
308+
getStartTimeMs()?.let { traceStartTimeMs ->
309+
if (applicationInitEndMs != null) {
329310
spanService.recordCompletedSpan(
330-
name = "embrace-init",
311+
name = "process-init",
331312
parent = this,
332-
startTimeMs = sdkInitStartMs,
333-
endTimeMs = sdkInitEndMs,
313+
startTimeMs = traceStartTimeMs,
314+
endTimeMs = applicationInitEndMs,
334315
)
335316
}
317+
}
336318

337-
val lastEventBeforeActivityInit = applicationInitEndMs ?: sdkInitEndMs
338-
if (lastEventBeforeActivityInit != null && firstActivityInitMs != null) {
339-
spanService.recordCompletedSpan(
340-
name = "activity-init-gap",
341-
parent = this,
342-
startTimeMs = lastEventBeforeActivityInit,
343-
endTimeMs = firstActivityInitMs,
344-
)
345-
}
319+
if (sdkInitStartMs != null && sdkInitEndMs != null) {
320+
spanService.recordCompletedSpan(
321+
name = "embrace-init",
322+
parent = this,
323+
startTimeMs = sdkInitStartMs,
324+
endTimeMs = sdkInitEndMs,
325+
)
326+
}
346327

347-
if (activityInitStartMs != null && activityInitEndMs != null) {
348-
spanService.recordCompletedSpan(
349-
name = "activity-create",
350-
parent = this,
351-
startTimeMs = activityInitStartMs,
352-
endTimeMs = activityInitEndMs,
353-
)
354-
}
355-
if (activityInitEndMs != null) {
356-
val uiLoadSpanName = if (endWithFrameDraw) {
357-
"first-frame-render"
358-
} else {
359-
"activity-resume"
360-
}
361-
spanService.recordCompletedSpan(
362-
name = uiLoadSpanName,
363-
parent = this,
364-
startTimeMs = activityInitEndMs,
365-
endTimeMs = traceEndTimeMs,
366-
)
328+
val lastEventBeforeActivityInit = applicationInitEndMs ?: sdkInitEndMs
329+
if (lastEventBeforeActivityInit != null && firstActivityInitMs != null) {
330+
spanService.recordCompletedSpan(
331+
name = "activity-init-gap",
332+
parent = this,
333+
startTimeMs = lastEventBeforeActivityInit,
334+
endTimeMs = firstActivityInitMs,
335+
)
336+
}
337+
338+
if (activityInitStartMs != null && activityInitEndMs != null) {
339+
spanService.recordCompletedSpan(
340+
name = "activity-create",
341+
parent = this,
342+
startTimeMs = activityInitStartMs,
343+
endTimeMs = activityInitEndMs,
344+
)
345+
}
346+
if (activityInitEndMs != null) {
347+
val uiLoadSpanName = if (endWithFrameDraw) {
348+
"first-frame-render"
349+
} else {
350+
"activity-resume"
367351
}
352+
spanService.recordCompletedSpan(
353+
name = uiLoadSpanName,
354+
parent = this,
355+
startTimeMs = activityInitEndMs,
356+
endTimeMs = traceEndTimeMs,
357+
)
368358
}
369-
} else {
370-
null
371359
}
372360
}
373361

0 commit comments

Comments
 (0)