Skip to content

Commit

Permalink
Merge pull request #329 from embrace-io/rename-services
Browse files Browse the repository at this point in the history
Combine & rename background activity + session services
  • Loading branch information
fractalwrench authored Jan 31, 2024
2 parents 729732b + 9066672 commit 9cc3fe9
Show file tree
Hide file tree
Showing 16 changed files with 242 additions and 302 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package io.embrace.android.embracesdk.injection
import io.embrace.android.embracesdk.ndk.NativeModule
import io.embrace.android.embracesdk.session.caching.PeriodicBackgroundActivityCacher
import io.embrace.android.embracesdk.session.caching.PeriodicSessionCacher
import io.embrace.android.embracesdk.session.message.BackgroundActivityService
import io.embrace.android.embracesdk.session.message.EmbraceBackgroundActivityService
import io.embrace.android.embracesdk.session.message.EmbraceSessionService
import io.embrace.android.embracesdk.session.message.PayloadFactory
import io.embrace.android.embracesdk.session.message.PayloadFactoryImpl
import io.embrace.android.embracesdk.session.message.PayloadMessageCollator
import io.embrace.android.embracesdk.session.message.SessionService
import io.embrace.android.embracesdk.session.orchestrator.OrchestratorBoundaryDelegate
import io.embrace.android.embracesdk.session.orchestrator.SessionOrchestrator
import io.embrace.android.embracesdk.session.orchestrator.SessionOrchestratorImpl
Expand All @@ -18,8 +16,7 @@ import io.embrace.android.embracesdk.worker.WorkerName
import io.embrace.android.embracesdk.worker.WorkerThreadModule

internal interface SessionModule {
val sessionService: SessionService
val backgroundActivityService: BackgroundActivityService?
val payloadFactory: PayloadFactory
val payloadMessageCollator: PayloadMessageCollator
val sessionPropertiesService: SessionPropertiesService
val sessionOrchestrator: SessionOrchestrator
Expand Down Expand Up @@ -90,15 +87,8 @@ internal class SessionModuleImpl(
)
}

override val sessionService: SessionService by singleton {
EmbraceSessionService(
deliveryModule.deliveryService,
payloadMessageCollator
)
}

override val backgroundActivityService: BackgroundActivityService? by singleton {
EmbraceBackgroundActivityService(
override val payloadFactory: PayloadFactory by singleton {
PayloadFactoryImpl(
deliveryModule.deliveryService,
payloadMessageCollator
)
Expand All @@ -119,8 +109,7 @@ internal class SessionModuleImpl(
override val sessionOrchestrator: SessionOrchestrator by singleton(LoadType.EAGER) {
SessionOrchestratorImpl(
essentialServiceModule.processStateService,
sessionService,
backgroundActivityService,
payloadFactory,
initModule.clock,
essentialServiceModule.configService,
essentialServiceModule.sessionIdTracker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import io.embrace.android.embracesdk.annotation.StartupActivity
import io.embrace.android.embracesdk.capture.orientation.OrientationService
import io.embrace.android.embracesdk.logging.InternalEmbraceLogger
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger
import io.embrace.android.embracesdk.session.message.SessionService
import io.embrace.android.embracesdk.utils.stream
import java.lang.ref.WeakReference
import java.util.concurrent.CopyOnWriteArrayList
Expand Down Expand Up @@ -170,16 +169,8 @@ internal class ActivityLifecycleTracker(
}

override fun addListener(listener: ActivityLifecycleListener) {
// assumption: we always need to run the Session service first, then everything else,
// because otherwise the session envelope will not be created. The ActivityListener
// could use separating from session handling, but that's a bigger change.
val priority = listener is SessionService
if (!listeners.contains(listener)) {
if (priority) {
listeners.add(0, listener)
} else {
listeners.addIfAbsent(listener)
}
listeners.addIfAbsent(listener)
}
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,30 @@ package io.embrace.android.embracesdk.session.message
import io.embrace.android.embracesdk.payload.Session
import io.embrace.android.embracesdk.payload.SessionMessage

internal interface SessionService {
/**
* Factory that creates session + background activity payloads.
*/
internal interface PayloadFactory {

/**
* Ends a background activity in response to a state event.
*/
fun startBackgroundActivityWithState(timestamp: Long, coldStart: Boolean): Session

/**
* Handles an uncaught exception, ending the session and saving the activity to disk.
*/
fun endBackgroundActivityWithCrash(initial: Session, timestamp: Long, crashId: String)

/**
* Starts a background activity in response to a state event.
*/
fun endBackgroundActivityWithState(initial: Session, timestamp: Long)

/**
* Provides a snapshot of the active background activity
*/
fun snapshotBackgroundActivity(initial: Session, timestamp: Long): SessionMessage

/**
* Starts a session in response to a state event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,68 @@ import io.embrace.android.embracesdk.payload.Session.LifeEventType
import io.embrace.android.embracesdk.payload.SessionMessage
import io.embrace.android.embracesdk.session.orchestrator.SessionSnapshotType

internal class EmbraceSessionService(
internal class PayloadFactoryImpl(
private val deliveryService: DeliveryService,
private val payloadMessageCollator: PayloadMessageCollator
) : SessionService {
) : PayloadFactory {

override fun startBackgroundActivityWithState(timestamp: Long, coldStart: Boolean): Session {
// kept for backwards compat. the backend expects the start time to be 1 ms greater
// than the adjacent session, and manually adjusts.
val time = when {
coldStart -> timestamp
else -> timestamp + 1
}
return payloadMessageCollator.buildInitialSession(
InitialEnvelopeParams.BackgroundActivityParams(
coldStart = coldStart,
startType = LifeEventType.BKGND_STATE,
startTime = time
)
)
}

override fun endBackgroundActivityWithState(initial: Session, timestamp: Long) {
// kept for backwards compat. the backend expects the start time to be 1 ms greater
// than the adjacent session, and manually adjusts.
val message = payloadMessageCollator.buildFinalBackgroundActivityMessage(
FinalEnvelopeParams.BackgroundActivityParams(
initial = initial,
endTime = timestamp - 1,
lifeEventType = LifeEventType.BKGND_STATE
)
)
deliveryService.saveBackgroundActivity(message)
deliveryService.sendBackgroundActivities()
}

override fun endBackgroundActivityWithCrash(
initial: Session,
timestamp: Long,
crashId: String
) {
val message = payloadMessageCollator.buildFinalBackgroundActivityMessage(
FinalEnvelopeParams.BackgroundActivityParams(
initial = initial,
endTime = timestamp,
lifeEventType = LifeEventType.BKGND_STATE,
crashId = crashId
)
)
deliveryService.saveBackgroundActivity(message)
}

override fun snapshotBackgroundActivity(initial: Session, timestamp: Long): SessionMessage {
val message = payloadMessageCollator.buildFinalBackgroundActivityMessage(
FinalEnvelopeParams.BackgroundActivityParams(
initial = initial,
endTime = timestamp,
lifeEventType = null
)
)
deliveryService.saveBackgroundActivity(message)
return message
}

override fun startSessionWithState(timestamp: Long, coldStart: Boolean): Session {
return payloadMessageCollator.buildInitialSession(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ import io.embrace.android.embracesdk.session.caching.PeriodicSessionCacher
import io.embrace.android.embracesdk.session.id.SessionIdTracker
import io.embrace.android.embracesdk.session.lifecycle.ProcessState
import io.embrace.android.embracesdk.session.lifecycle.ProcessStateService
import io.embrace.android.embracesdk.session.message.BackgroundActivityService
import io.embrace.android.embracesdk.session.message.SessionService
import io.embrace.android.embracesdk.session.message.PayloadFactory

internal class SessionOrchestratorImpl(
private val processStateService: ProcessStateService,
private val sessionService: SessionService,
backgroundActivityServiceImpl: BackgroundActivityService?,
private val payloadFactory: PayloadFactory,
private val clock: Clock,
private val configService: ConfigService,
private val sessionIdTracker: SessionIdTracker,
Expand All @@ -38,10 +36,10 @@ internal class SessionOrchestratorImpl(
else -> ProcessState.FOREGROUND
}

private val backgroundActivityGate = ConfigGate(backgroundActivityServiceImpl) {
private val backgroundActivityGate = ConfigGate(payloadFactory) {
configService.isBackgroundActivityCaptureEnabled()
}
private val backgroundActivityService: BackgroundActivityService?
private val backgroundActivityFactory: PayloadFactory?
get() = backgroundActivityGate.getService()

init {
Expand All @@ -57,9 +55,9 @@ internal class SessionOrchestratorImpl(
timestamp = timestamp,
newSessionAction = {
if (state == ProcessState.BACKGROUND) {
backgroundActivityService?.startBackgroundActivityWithState(timestamp, true)
backgroundActivityFactory?.startBackgroundActivityWithState(timestamp, true)
} else {
sessionService.startSessionWithState(timestamp, true)
payloadFactory.startSessionWithState(timestamp, true)
}
}
)
Expand All @@ -70,10 +68,10 @@ internal class SessionOrchestratorImpl(
transitionType = TransitionType.ON_FOREGROUND,
timestamp = timestamp,
oldSessionAction = { initial: Session ->
backgroundActivityService?.endBackgroundActivityWithState(initial, timestamp)
backgroundActivityFactory?.endBackgroundActivityWithState(initial, timestamp)
},
newSessionAction = {
sessionService.startSessionWithState(timestamp, coldStart)
payloadFactory.startSessionWithState(timestamp, coldStart)
},
earlyTerminationCondition = {
return@transitionState shouldRunOnForeground(state)
Expand All @@ -86,10 +84,10 @@ internal class SessionOrchestratorImpl(
transitionType = TransitionType.ON_BACKGROUND,
timestamp = timestamp,
oldSessionAction = { initial: Session ->
sessionService.endSessionWithState(initial, timestamp)
payloadFactory.endSessionWithState(initial, timestamp)
},
newSessionAction = {
backgroundActivityService?.startBackgroundActivityWithState(timestamp, false)
backgroundActivityFactory?.startBackgroundActivityWithState(timestamp, false)
},
earlyTerminationCondition = {
return@transitionState shouldRunOnBackground(state)
Expand All @@ -104,10 +102,10 @@ internal class SessionOrchestratorImpl(
timestamp = timestamp,
clearUserInfo = clearUserInfo,
oldSessionAction = { initial: Session ->
sessionService.endSessionWithManual(initial, timestamp)
payloadFactory.endSessionWithManual(initial, timestamp)
},
newSessionAction = {
sessionService.startSessionWithManual(timestamp)
payloadFactory.startSessionWithManual(timestamp)
},
earlyTerminationCondition = {
return@transitionState shouldEndManualSession(
Expand All @@ -127,13 +125,13 @@ internal class SessionOrchestratorImpl(
timestamp = timestamp,
oldSessionAction = { initial: Session ->
if (processStateService.isInBackground) {
backgroundActivityService?.endBackgroundActivityWithCrash(
backgroundActivityFactory?.endBackgroundActivityWithCrash(
initial,
timestamp,
crashId
)
} else {
sessionService.endSessionWithCrash(initial, timestamp, crashId)
payloadFactory.endSessionWithCrash(initial, timestamp, crashId)
}
}
)
Expand Down Expand Up @@ -229,7 +227,7 @@ internal class SessionOrchestratorImpl(
ProcessState.FOREGROUND -> {
periodicSessionCacher.start {
synchronized(lock) {
sessionService.snapshotSession(newState, clock.now())
payloadFactory.snapshotSession(newState, clock.now())
}
}
}
Expand All @@ -240,7 +238,7 @@ internal class SessionOrchestratorImpl(
private fun scheduleBackgroundActivitySave(initial: Session) {
periodicBackgroundActivityCacher.scheduleSave {
synchronized(lock) {
backgroundActivityService?.snapshotBackgroundActivity(initial, clock.now())
backgroundActivityFactory?.snapshotBackgroundActivity(initial, clock.now())
}
}
}
Expand Down
Loading

0 comments on commit 9cc3fe9

Please sign in to comment.