Skip to content

Commit

Permalink
refactor: extract session message collator
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Nov 15, 2023
1 parent e94b282 commit 14f903b
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.embrace.android.embracesdk.session.EmbraceBackgroundActivityService
import io.embrace.android.embracesdk.session.EmbraceSessionProperties
import io.embrace.android.embracesdk.session.EmbraceSessionService
import io.embrace.android.embracesdk.session.SessionHandler
import io.embrace.android.embracesdk.session.SessionMessageCollator
import io.embrace.android.embracesdk.session.SessionService
import io.embrace.android.embracesdk.worker.ExecutorName
import io.embrace.android.embracesdk.worker.WorkerThreadModule
Expand All @@ -14,6 +15,7 @@ internal interface SessionModule {
val sessionHandler: SessionHandler
val sessionService: SessionService
val backgroundActivityService: BackgroundActivityService?
val sessionMessageCollator: SessionMessageCollator
}

internal class SessionModuleImpl(
Expand All @@ -31,6 +33,24 @@ internal class SessionModuleImpl(
workerThreadModule: WorkerThreadModule
) : SessionModule {

override val sessionMessageCollator: SessionMessageCollator by singleton {
SessionMessageCollator(
essentialServiceModule.configService,
essentialServiceModule.metadataService,
dataContainerModule.eventService,
customerLogModule.remoteLogger,
sdkObservabilityModule.exceptionService,
dataContainerModule.performanceInfoService,
dataCaptureServiceModule.webviewService,
dataCaptureServiceModule.activityLifecycleBreadcrumbService,
dataCaptureServiceModule.thermalStatusService,
nativeModule.nativeThreadSamplerService,
dataCaptureServiceModule.breadcrumbService,
essentialServiceModule.userService,
initModule.clock
)
}

override val sessionHandler: SessionHandler by singleton {
SessionHandler(
coreModule.logger,
Expand All @@ -42,16 +62,10 @@ internal class SessionModuleImpl(
dataCaptureServiceModule.breadcrumbService,
essentialServiceModule.activityLifecycleTracker,
nativeModule.ndkService,
dataContainerModule.eventService,
customerLogModule.remoteLogger,
sdkObservabilityModule.exceptionService,
dataContainerModule.performanceInfoService,
essentialServiceModule.memoryCleanerService,
deliveryModule.deliveryService,
dataCaptureServiceModule.webviewService,
dataCaptureServiceModule.activityLifecycleBreadcrumbService,
dataCaptureServiceModule.thermalStatusService,
nativeModule.nativeThreadSamplerService,
sessionMessageCollator,
initModule.clock,
workerThreadModule.scheduledExecutor(ExecutorName.SESSION_CLOSER),
workerThreadModule.scheduledExecutor(ExecutorName.SESSION_CACHING)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
package io.embrace.android.embracesdk.session

import androidx.annotation.VisibleForTesting
import io.embrace.android.embracesdk.anr.ndk.NativeThreadSamplerService
import io.embrace.android.embracesdk.capture.PerformanceInfoService
import io.embrace.android.embracesdk.capture.connectivity.NetworkConnectivityService
import io.embrace.android.embracesdk.capture.crumbs.BreadcrumbService
import io.embrace.android.embracesdk.capture.crumbs.activity.ActivityLifecycleBreadcrumbService
import io.embrace.android.embracesdk.capture.metadata.MetadataService
import io.embrace.android.embracesdk.capture.thermalstate.ThermalStatusService
import io.embrace.android.embracesdk.capture.user.UserService
import io.embrace.android.embracesdk.capture.webview.WebViewService
import io.embrace.android.embracesdk.comms.delivery.DeliveryService
import io.embrace.android.embracesdk.comms.delivery.SessionMessageState
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.event.EmbraceRemoteLogger
import io.embrace.android.embracesdk.event.EventService
import io.embrace.android.embracesdk.internal.MessageType
import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.internal.spans.EmbraceSpanData
Expand All @@ -23,7 +16,6 @@ import io.embrace.android.embracesdk.logging.EmbraceInternalErrorService
import io.embrace.android.embracesdk.logging.InternalEmbraceLogger
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Companion.logDeveloper
import io.embrace.android.embracesdk.ndk.NdkService
import io.embrace.android.embracesdk.payload.BetaFeatures
import io.embrace.android.embracesdk.payload.Session
import io.embrace.android.embracesdk.payload.Session.SessionLifeEventType
import io.embrace.android.embracesdk.payload.SessionMessage
Expand All @@ -46,16 +38,10 @@ internal class SessionHandler(
private val breadcrumbService: BreadcrumbService,
private val activityLifecycleTracker: ActivityTracker,
private val ndkService: NdkService,
private val eventService: EventService,
private val remoteLogger: EmbraceRemoteLogger,
private val exceptionService: EmbraceInternalErrorService,
private val performanceInfoService: PerformanceInfoService,
private val memoryCleanerService: MemoryCleanerService,
private val deliveryService: DeliveryService,
private val webViewService: WebViewService,
private val activityLifecycleBreadcrumbService: ActivityLifecycleBreadcrumbService?,
private val thermalStatusService: ThermalStatusService,
private val nativeThreadSamplerService: NativeThreadSamplerService?,
private val sessionMessageCollator: SessionMessageCollator,
private val clock: Clock,
private val automaticSessionStopper: ScheduledExecutorService,
private val sessionPeriodicCacheExecutorService: ScheduledExecutorService
Expand Down Expand Up @@ -95,7 +81,7 @@ internal class SessionHandler(
// Record the connection type at the start of the session.
networkConnectivityService.networkStatusOnSessionStarted(session.startTime)

val sessionMessage = buildStartSessionMessage(session)
val sessionMessage = sessionMessageCollator.buildStartSessionMessage(session)

metadataService.setActiveSessionId(session.sessionId)

Expand Down Expand Up @@ -245,123 +231,6 @@ internal class SessionHandler(
}
}

@Suppress("ComplexMethod")
private fun buildEndSessionMessage(
originSession: Session,
endedCleanly: Boolean,
forceQuit: Boolean,
crashId: String?,
endType: SessionLifeEventType,
sessionProperties: EmbraceSessionProperties,
sdkStartupDuration: Long,
endTime: Long,
spans: List<EmbraceSpanData>? = null
): SessionMessage {
val startTime: Long = originSession.startTime

// if it's a crash session, then add the stacktrace to the session payload
val crashReportId = when {
!crashId.isNullOrEmpty() -> crashId
else -> null
}
val terminationTime = when {
forceQuit -> endTime
else -> null
}
val receivedTermination = when {
forceQuit -> true
else -> null
}
// We don't set end time for force-quit, as the API interprets this to be a clean
// termination
val endTimeVal = when {
forceQuit -> null
else -> endTime
}

val sdkStartDuration = when (originSession.isColdStart) {
true -> sdkStartupDuration
false -> null
}

val startupEventInfo = eventService.getStartupMomentInfo()

val startupDuration = when (originSession.isColdStart && startupEventInfo != null) {
true -> startupEventInfo.duration
false -> null
}
val startupThreshold = when (originSession.isColdStart && startupEventInfo != null) {
true -> startupEventInfo.threshold
false -> null
}

val betaFeatures = when (configService.sdkModeBehavior.isBetaFeaturesEnabled()) {
false -> null
else -> BetaFeatures(
thermalStates = thermalStatusService.getCapturedData(),
activityLifecycleBreadcrumbs = activityLifecycleBreadcrumbService?.getCapturedData()
)
}

val endSession = originSession.copy(
isEndedCleanly = endedCleanly,
appState = EmbraceSessionService.APPLICATION_STATE_FOREGROUND,
messageType = MESSAGE_TYPE_END,
eventIds = eventService.findEventIdsForSession(startTime, endTime),
infoLogIds = remoteLogger.findInfoLogIds(startTime, endTime),
warningLogIds = remoteLogger.findWarningLogIds(startTime, endTime),
errorLogIds = remoteLogger.findErrorLogIds(startTime, endTime),
networkLogIds = remoteLogger.findNetworkLogIds(startTime, endTime),
infoLogsAttemptedToSend = remoteLogger.getInfoLogsAttemptedToSend(),
warnLogsAttemptedToSend = remoteLogger.getWarnLogsAttemptedToSend(),
errorLogsAttemptedToSend = remoteLogger.getErrorLogsAttemptedToSend(),
lastHeartbeatTime = clock.now(),
properties = sessionProperties.get(),
endType = endType,
unhandledExceptions = remoteLogger.getUnhandledExceptionsSent(),
webViewInfo = webViewService.getCapturedData(),
crashReportId = crashReportId,
terminationTime = terminationTime,
isReceivedTermination = receivedTermination,
endTime = endTimeVal,
sdkStartupDuration = sdkStartDuration,
startupDuration = startupDuration,
startupThreshold = startupThreshold,
user = userService.getUserInfo(),
betaFeatures = betaFeatures,
symbols = nativeThreadSamplerService?.getNativeSymbols()
)

val performanceInfo = performanceInfoService.getSessionPerformanceInfo(
startTime,
endTime,
originSession.isColdStart,
originSession.isReceivedTermination
)

val appInfo = metadataService.getAppInfo()
val deviceInfo = metadataService.getDeviceInfo()
val breadcrumbs = breadcrumbService.getBreadcrumbs(startTime, endTime)

val endSessionWithAllErrors = endSession.copy(exceptionError = exceptionService.currentExceptionError)

return SessionMessage(
session = endSessionWithAllErrors,
userInfo = endSessionWithAllErrors.user,
appInfo = appInfo,
deviceInfo = deviceInfo,
performanceInfo = performanceInfo.copy(),
breadcrumbs = breadcrumbs,
spans = spans
)
}

private fun buildStartSessionMessage(session: Session) = SessionMessage(
session = session,
appInfo = metadataService.getAppInfo(),
deviceInfo = metadataService.getDeviceInfo()
)

/**
* It builds an end active session message, it sanitizes it, it performs all types of memory cleaning,
* it updates cache and it sends it to our servers.
Expand All @@ -387,7 +256,7 @@ internal class SessionHandler(
return
}

val fullEndSessionMessage = buildEndSessionMessage(
val fullEndSessionMessage = sessionMessageCollator.buildEndSessionMessage(
/* we are previously checking in allowSessionToEnd that originSession != null */
originSession!!,
endedCleanly = true,
Expand Down Expand Up @@ -439,7 +308,7 @@ internal class SessionHandler(
// let's not overwrite the crash info with the periodic caching
stopPeriodicSessionCaching()

val fullEndSessionMessage = buildEndSessionMessage(
val fullEndSessionMessage = sessionMessageCollator.buildEndSessionMessage(
originSession,
endedCleanly = false,
forceQuit = false,
Expand Down Expand Up @@ -470,7 +339,7 @@ internal class SessionHandler(
return null
}

val fullEndSessionMessage = buildEndSessionMessage(
val fullEndSessionMessage = sessionMessageCollator.buildEndSessionMessage(
activeSession,
endedCleanly = false,
forceQuit = true,
Expand Down Expand Up @@ -572,13 +441,3 @@ internal class SessionHandler(
}
}
}

/**
* Signals to the API the start of a session.
*/
internal const val MESSAGE_TYPE_START = "st"

/**
* Signals to the API the end of a session.
*/
private const val MESSAGE_TYPE_END = "en"
Loading

0 comments on commit 14f903b

Please sign in to comment.