Skip to content

Commit c958f8a

Browse files
author
Sergey Chelombitko
committed
Handle cancellation in withRetry
1 parent 5bb61f1 commit c958f8a

File tree

3 files changed

+29
-23
lines changed

3 files changed

+29
-23
lines changed

core/src/main/kotlin/com/malinskiy/marathon/execution/Retry.kt

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package com.malinskiy.marathon.execution
22

3-
import kotlinx.coroutines.delay
3+
import kotlinx.coroutines.currentCoroutineContext
4+
import kotlinx.coroutines.ensureActive
5+
import kotlinx.coroutines.isActive
6+
import kotlinx.coroutines.time.delay
7+
import java.time.Duration
8+
9+
suspend fun withRetry(maxAttempts: Int, retryDelay: Duration, block: suspend () -> Unit) {
10+
check(maxAttempts >= 1) { "maxAttempts must be >= 1" }
411

5-
@Suppress("TooGenericExceptionCaught")
6-
suspend fun <T> withRetry(attempts: Int, delayTime: Long = 0, f: suspend () -> T): T {
712
var attempt = 1
8-
while (true) {
13+
while (currentCoroutineContext().isActive) {
914
try {
10-
return f()
11-
} catch (th: Throwable) {
12-
if (attempt == attempts) {
13-
throw th
15+
return block()
16+
} catch (@Suppress("TooGenericExceptionCaught") e: Throwable) {
17+
currentCoroutineContext().ensureActive()
18+
if (attempt == maxAttempts) {
19+
throw e
1420
} else {
15-
delay(delayTime)
21+
delay(retryDelay)
1622
}
1723
}
1824
++attempt

core/src/main/kotlin/com/malinskiy/marathon/execution/device/DeviceActor.kt

+10-12
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import kotlinx.coroutines.CompletionHandler
2121
import kotlinx.coroutines.Job
2222
import kotlinx.coroutines.async
2323
import kotlinx.coroutines.channels.SendChannel
24-
import kotlinx.coroutines.isActive
2524
import kotlinx.coroutines.launch
25+
import java.time.Duration
2626
import java.time.Instant
2727
import kotlin.coroutines.CoroutineContext
2828

@@ -157,18 +157,16 @@ class DeviceActor(
157157

158158
private fun initialize() {
159159
logger.debug("[{}] Initializing", device.serialNumber)
160-
job = scope.async {
160+
job = scope.launch {
161161
try {
162-
withRetry(30, 10000) {
163-
if (isActive) {
164-
try {
165-
device.prepare(configuration)
166-
} catch (e: CancellationException) {
167-
throw e
168-
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
169-
logger.debug("[{}] Initialization failed. Retrying", device.serialNumber, e)
170-
throw e
171-
}
162+
withRetry(maxAttempts = 30, retryDelay = Duration.ofSeconds(10)) {
163+
try {
164+
device.prepare(configuration)
165+
} catch (e: CancellationException) {
166+
throw e
167+
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
168+
logger.debug("[{}] Initialization failed. Retrying", device.serialNumber, e)
169+
throw e
172170
}
173171
}
174172
state.transition(DeviceEvent.Complete)

vendor/vendor-android/ddmlib/src/main/kotlin/com/malinskiy/marathon/android/AndroidAppInstaller.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.malinskiy.marathon.execution.withRetry
77
import com.malinskiy.marathon.io.FileHasher
88
import com.malinskiy.marathon.log.MarathonLogging
99
import java.io.File
10+
import java.time.Duration
1011
import java.time.Instant
1112
import kotlin.system.measureTimeMillis
1213

@@ -39,7 +40,7 @@ class AndroidAppInstaller(
3940

4041
@Suppress("TooGenericExceptionThrown")
4142
private suspend fun ensureInstalled(device: AndroidDevice, appPackage: String, appApk: File) {
42-
withRetry(attempts = MAX_RETIRES, delayTime = 1000) {
43+
withRetry(maxAttempts = MAX_INSTALLATION_ATTEMPTS, retryDelay = INSTALLATION_RETRY_DELAY) {
4344
try {
4445
val checkStarted = Instant.now()
4546
val fileHash = fileHasher.getHash(appApk)
@@ -138,7 +139,8 @@ class AndroidAppInstaller(
138139
}
139140

140141
companion object {
141-
private const val MAX_RETIRES = 3
142+
private const val MAX_INSTALLATION_ATTEMPTS = 3
143+
private val INSTALLATION_RETRY_DELAY = Duration.ofSeconds(1)
142144
private const val MARSHMALLOW_VERSION_CODE = 23
143145
private const val MD5_HASH_SIZE = 32
144146
private const val INSTALLED_TEST_APPS_SCRIPT = "pm list packages -3 | grep -E '\\.test\$' | tr -d '\\r' | cut -d ':' -f 2"

0 commit comments

Comments
 (0)