Skip to content

Commit

Permalink
refactor: encapsulate executors in background/scheduled workers
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Jan 8, 2024
1 parent b072706 commit af96b33
Show file tree
Hide file tree
Showing 68 changed files with 472 additions and 310 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.concurrency.BlockingScheduledExecutorService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.getSentBackgroundActivities
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.verifyBgActivityMessage
import io.embrace.android.embracesdk.verifySessionHappened
import io.embrace.android.embracesdk.worker.ExecutorName
import io.embrace.android.embracesdk.worker.WorkerName
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import io.embrace.android.embracesdk.getLastSavedSessionMessage
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.verifySessionHappened
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.runner.RunWith

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ package io.embrace.android.embracesdk.session

import io.embrace.android.embracesdk.concurrency.BlockingScheduledExecutorService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.worker.ExecutorName
import io.embrace.android.embracesdk.worker.WorkerName
import io.embrace.android.embracesdk.worker.ScheduledWorker
import io.embrace.android.embracesdk.worker.WorkerThreadModule
import io.embrace.android.embracesdk.worker.WorkerThreadModuleImpl
import java.util.concurrent.ScheduledExecutorService

internal class FakeWorkerThreadModule(
fakeClock: FakeClock,
private val name: ExecutorName,
private val name: WorkerName,
private val base: WorkerThreadModule = WorkerThreadModuleImpl()
) : WorkerThreadModule by base {

private val executor = BlockingScheduledExecutorService(fakeClock)
val executor = BlockingScheduledExecutorService(fakeClock)

override fun scheduledExecutor(executorName: ExecutorName): ScheduledExecutorService {
return when (executorName) {
name -> executor
else -> base.scheduledExecutor(executorName)
private val worker = ScheduledWorker(executor)

override fun scheduledWorker(workerName: WorkerName): ScheduledWorker {
return when (workerName) {
name -> worker
else -> base.scheduledWorker(workerName)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@ package io.embrace.android.embracesdk.session
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.concurrency.BlockingScheduledExecutorService
import io.embrace.android.embracesdk.config.local.SessionLocalConfig
import io.embrace.android.embracesdk.config.remote.RemoteConfig
import io.embrace.android.embracesdk.config.remote.SessionRemoteConfig
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.fakeSessionBehavior
import io.embrace.android.embracesdk.getLastSavedSessionMessage
import io.embrace.android.embracesdk.getLastSentSessionMessage
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.verifySessionHappened
import io.embrace.android.embracesdk.verifySessionMessage
import io.embrace.android.embracesdk.worker.ExecutorName.*
import io.embrace.android.embracesdk.worker.WorkerName.*
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNull
import org.junit.Rule
import org.junit.Test
Expand All @@ -42,8 +33,7 @@ internal class PeriodicSessionCacheTest {
@Test
fun `session is periodically cached`() {
with(testRule) {
val executor =
harness.workerThreadModule.scheduledExecutor(PERIODIC_CACHE) as BlockingScheduledExecutorService
val executor = (harness.workerThreadModule as FakeWorkerThreadModule).executor

harness.recordSession {
executor.runCurrentlyBlocked()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import io.embrace.android.embracesdk.fakes.fakeSessionBehavior
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.verifySessionHappened
import io.embrace.android.embracesdk.worker.ExecutorName
import io.embrace.android.embracesdk.worker.ExecutorName.*
import io.embrace.android.embracesdk.worker.WorkerThreadModule
import io.embrace.android.embracesdk.worker.WorkerThreadModuleImpl
import java.util.concurrent.ExecutorService
import java.util.concurrent.ScheduledExecutorService
import io.embrace.android.embracesdk.worker.WorkerName.*
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Rule
Expand All @@ -42,8 +37,8 @@ internal class TimedSessionTest {
@Test
fun `timed session automatically ends session`() {
with(testRule) {
val executor =
harness.workerThreadModule.scheduledExecutor(BACKGROUND_REGISTRATION) as BlockingScheduledExecutorService
val executor = (harness.workerThreadModule as FakeWorkerThreadModule).executor

harness.fakeConfigService.sessionBehavior = fakeSessionBehavior(
localCfg = { SessionLocalConfig(90) }) {
RemoteConfig(sessionConfig = SessionRemoteConfig(isEnabled = true))
Expand All @@ -67,8 +62,7 @@ internal class TimedSessionTest {
@Test
fun `timed session has no effect when config disabled`() {
with(testRule) {
val executor =
harness.workerThreadModule.scheduledExecutor(BACKGROUND_REGISTRATION) as BlockingScheduledExecutorService
val executor = (harness.workerThreadModule as FakeWorkerThreadModule).executor
harness.fakeConfigService.sessionBehavior = fakeSessionBehavior {
RemoteConfig(sessionConfig = SessionRemoteConfig(isEnabled = true))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
import io.embrace.android.embracesdk.session.properties.SessionPropertiesService;
import io.embrace.android.embracesdk.telemetry.TelemetryService;
import io.embrace.android.embracesdk.utils.PropertyUtils;
import io.embrace.android.embracesdk.worker.ExecutorName;
import io.embrace.android.embracesdk.worker.WorkerName;
import io.embrace.android.embracesdk.worker.WorkerThreadModule;
import io.embrace.android.embracesdk.worker.WorkerThreadModuleImpl;
import kotlin.Lazy;
Expand Down Expand Up @@ -364,7 +364,7 @@ private void startImpl(@NonNull Context context,
final WorkerThreadModule nonNullWorkerThreadModule = workerThreadModuleSupplier.invoke();
workerThreadModule = nonNullWorkerThreadModule;

nonNullWorkerThreadModule.backgroundExecutor(ExecutorName.BACKGROUND_REGISTRATION).submit(() -> {
nonNullWorkerThreadModule.backgroundWorker(WorkerName.BACKGROUND_REGISTRATION).submit(() -> {
final SpansService spansService = initModule.getSpansService();
if (spansService instanceof Initializable) {
((Initializable) spansService).initializeService(TimeUnit.MILLISECONDS.toNanos(startTime));
Expand Down Expand Up @@ -677,7 +677,7 @@ private void startImpl(@NonNull Context context,
private void loadCrashVerifier(CrashModule crashModule, WorkerThreadModule workerThreadModule) {
crashVerifier = crashModule.getLastRunCrashVerifier();
crashVerifier.readAndCleanMarkerAsync(
workerThreadModule.backgroundExecutor(ExecutorName.BACKGROUND_REGISTRATION)
workerThreadModule.backgroundWorker(WorkerName.BACKGROUND_REGISTRATION)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger
import io.embrace.android.embracesdk.payload.NativeThreadAnrInterval
import io.embrace.android.embracesdk.payload.NativeThreadAnrSample
import io.embrace.android.embracesdk.payload.mapThreadState
import io.embrace.android.embracesdk.worker.ScheduledWorker
import java.util.Random
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit

/**
Expand All @@ -24,7 +24,7 @@ internal class EmbraceNativeThreadSamplerService @JvmOverloads constructor(
private val random: Random = Random(),
private val logger: InternalEmbraceLogger = InternalStaticEmbraceLogger.logger,
private val delegate: NdkDelegate = NativeThreadSamplerNdkDelegate(),
private val executorService: ScheduledExecutorService,
private val scheduledWorker: ScheduledWorker,
private val deviceArchitecture: DeviceArchitecture
) : NativeThreadSamplerService {

Expand Down Expand Up @@ -139,9 +139,7 @@ internal class EmbraceNativeThreadSamplerService @JvmOverloads constructor(
intervalMs
)

executorService.schedule({
fetchIntervals()
}, intervalMs * MAX_NATIVE_SAMPLES, TimeUnit.MILLISECONDS)
scheduledWorker.schedule<Unit>(::fetchIntervals, intervalMs * MAX_NATIVE_SAMPLES, TimeUnit.MILLISECONDS)
}
}
count++
Expand All @@ -154,7 +152,7 @@ internal class EmbraceNativeThreadSamplerService @JvmOverloads constructor(
)

if (sampling) {
executorService.submit {
scheduledWorker.submit {
logger.logDeveloper(
"EmbraceNativeThreadSamplerService",
"Fetching samples on JVM bg thread"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import io.embrace.android.embracesdk.payload.AppExitInfoData
import io.embrace.android.embracesdk.payload.BlobMessage
import io.embrace.android.embracesdk.payload.BlobSession
import io.embrace.android.embracesdk.prefs.PreferencesService
import io.embrace.android.embracesdk.worker.BackgroundWorker
import java.io.IOException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Future
import java.util.concurrent.atomic.AtomicBoolean

@RequiresApi(VERSION_CODES.R)
internal class EmbraceApplicationExitInfoService(
private val executorService: ExecutorService,
private val backgroundWorker: BackgroundWorker,
private val configService: ConfigService,
private val activityManager: ActivityManager?,
private val preferencesService: PreferencesService,
Expand Down Expand Up @@ -54,7 +54,7 @@ internal class EmbraceApplicationExitInfoService(
}

private fun startService() {
backgroundExecution = executorService.submit {
backgroundExecution = backgroundWorker.submit {
try {
processApplicationExitInfo()
} catch (exc: Throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.logging.InternalEmbraceLogger
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Companion.logDebug
import io.embrace.android.embracesdk.payload.Interval
import io.embrace.android.embracesdk.worker.BackgroundWorker
import java.net.Inet4Address
import java.net.NetworkInterface
import java.util.NavigableMap
import java.util.TreeMap
import java.util.concurrent.ExecutorService

@Suppress("DEPRECATION") // uses deprecated APIs for backwards compat
internal class EmbraceNetworkConnectivityService(
private val context: Context,
private val clock: Clock,
private val registrationExecutorService: ExecutorService,
private val backgroundWorker: BackgroundWorker,
private val logger: InternalEmbraceLogger,
private val connectivityManager: ConnectivityManager?,
private val isNetworkCaptureEnabled: Boolean
Expand Down Expand Up @@ -131,7 +131,7 @@ internal class EmbraceNetworkConnectivityService(
lastNetworkStatus == null || lastNetworkStatus != newNetworkStatus

private fun registerConnectivityActionReceiver() {
registrationExecutorService.submit {
backgroundWorker.submit {
try {
context.registerReceiver(this, intentFilter)
} catch (ex: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ import io.embrace.android.embracesdk.payload.DiskUsage
import io.embrace.android.embracesdk.prefs.PreferencesService
import io.embrace.android.embracesdk.session.lifecycle.ActivityLifecycleListener
import io.embrace.android.embracesdk.session.lifecycle.ProcessStateService
import io.embrace.android.embracesdk.utils.eagerLazyLoad
import io.embrace.android.embracesdk.worker.BackgroundWorker
import io.embrace.android.embracesdk.worker.eagerLazyLoad
import java.io.ByteArrayOutputStream
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.InputStream
import java.security.MessageDigest
import java.util.Locale
import java.util.concurrent.Callable
import java.util.concurrent.ExecutorService

/**
* Provides information about the state of the device, retrieved from Android system services,
Expand Down Expand Up @@ -67,7 +67,7 @@ internal class EmbraceMetadataService private constructor(
buildGuid: String?,
unitySdkVersion: String?,
rnSdkVersion: String?,
private val metadataRetrieveExecutorService: ExecutorService,
private val metadataBackgroundWorker: BackgroundWorker,
private val clock: Clock,
private val embraceCpuInfoDelegate: CpuInfoDelegate,
private val deviceArchitecture: DeviceArchitecture
Expand Down Expand Up @@ -152,7 +152,7 @@ internal class EmbraceMetadataService private constructor(
logDeveloper("EmbraceMetadataService", "Additional device info already exists")
return
}
metadataRetrieveExecutorService.submit {
metadataBackgroundWorker.submit {
logDeveloper("EmbraceMetadataService", "Async retrieve cpuName & egl")
val storedCpuName = preferencesService.cpuName
val storedEgl = preferencesService.egl
Expand All @@ -179,7 +179,7 @@ internal class EmbraceMetadataService private constructor(
logDeveloper("EmbraceMetadataService", "Screen resolution already exists")
return
}
metadataRetrieveExecutorService.submit {
metadataBackgroundWorker.submit {
logDeveloper("EmbraceMetadataService", "Async retrieve screen resolution")
val storedScreenResolution = preferencesService.screenResolution
// get from shared preferences
Expand Down Expand Up @@ -207,7 +207,7 @@ internal class EmbraceMetadataService private constructor(
logDeveloper("EmbraceMetadataService", "Jailbroken already exists")
return
}
metadataRetrieveExecutorService.submit {
metadataBackgroundWorker.submit {
logDeveloper("EmbraceMetadataService", "Async retrieve jailbroken")
val storedIsJailbroken = preferencesService.jailbroken
// load value from shared preferences
Expand All @@ -224,7 +224,7 @@ internal class EmbraceMetadataService private constructor(
}

fun asyncRetrieveDiskUsage(isAndroid26OrAbove: Boolean) {
metadataRetrieveExecutorService.submit {
metadataBackgroundWorker.submit {
logDeveloper("EmbraceMetadataService", "Async retrieve disk usage")
val free = MetadataUtils.getInternalStorageFreeCapacity(statFs.value)
if (isAndroid26OrAbove && configService.autoDataCaptureBehavior.isDiskUsageReportingEnabled()) {
Expand Down Expand Up @@ -441,7 +441,7 @@ internal class EmbraceMetadataService private constructor(
preferencesService.javaScriptBundleURL = jsBundleIdUrl

// get the hashed bundle ID file from the bundle ID URL
reactNativeBundleId = metadataRetrieveExecutorService.eagerLazyLoad(
reactNativeBundleId = metadataBackgroundWorker.eagerLazyLoad(
Callable {
computeReactNativeBundleId(
context,
Expand Down Expand Up @@ -513,7 +513,7 @@ internal class EmbraceMetadataService private constructor(
appFramework: AppFramework,
preferencesService: PreferencesService,
processStateService: ProcessStateService,
metadataRetrieveExecutorService: ExecutorService,
metadataBackgroundWorker: BackgroundWorker,
storageStatsManager: StorageStatsManager?,
windowManager: WindowManager?,
activityManager: ActivityManager?,
Expand Down Expand Up @@ -551,7 +551,7 @@ internal class EmbraceMetadataService private constructor(
val reactNativeBundleId: Lazy<String?>
if (appFramework == AppFramework.REACT_NATIVE) {
reactNativeBundleId =
metadataRetrieveExecutorService.eagerLazyLoad(
metadataBackgroundWorker.eagerLazyLoad(
Callable {
val lastKnownJsBundleUrl = preferencesService.javaScriptBundleURL
if (lastKnownJsBundleUrl != null) {
Expand Down Expand Up @@ -633,7 +633,7 @@ internal class EmbraceMetadataService private constructor(
buildGuid,
unitySdkVersion,
rnSdkVersion,
metadataRetrieveExecutorService,
metadataBackgroundWorker,
clock,
embraceCpuInfoDelegate,
deviceArchitecture
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Compani
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Companion.logDeveloper
import io.embrace.android.embracesdk.payload.PowerModeInterval
import io.embrace.android.embracesdk.session.lifecycle.ProcessStateListener
import java.util.concurrent.ExecutorService
import io.embrace.android.embracesdk.worker.BackgroundWorker

internal class EmbracePowerSaveModeService(
private val context: Context,
private val executorService: ExecutorService,
private val backgroundWorker: BackgroundWorker,
private val clock: Clock,
private val powerManager: PowerManager?
) : BroadcastReceiver(), PowerSaveModeService, ProcessStateListener {
Expand All @@ -36,7 +36,7 @@ internal class EmbracePowerSaveModeService(
}

private fun registerPowerSaveModeReceiver() {
executorService.submit {
backgroundWorker.submit {
try {
context.registerReceiver(this, powerSaveIntentFilter)
logDeveloper(tag, "registered power save mode changed")
Expand Down
Loading

0 comments on commit af96b33

Please sign in to comment.