I have a retry policy which takes in a lambda, launches a CoroutineScope, increments a retry counter, checks if the maximum retries are reached, calculates a waitTime based on the retry count, delays the scope for this time and finally calls the lambda:
fun connectionRetryPolicy(block: () -> Unit) {
Timber.d("connectionRetryPolicy: called")
// Launch the coroutine to wait for a specific delay
val scope = CoroutineScope(Job() + Dispatchers.Main)
scope.launch {
// Get and increment the current retry counter
val counter = retryCounter.getAndIncrement()
// Check if the counter is smaller than the maximum retry count and if so, wait a bit and execute the given function
if (counter < maxRetry) {
// Calculate the time to be waited
val waitTime: Long = (2f.pow(counter) * baseDelayMillis).toLong()
// Delay the scope for the calculated time
delay(waitTime)
// Execute the given function
block()
}
// Else, throw an exception
else {
throw FirebaseNetworkException("Retry count reached")
}
}
}
This method is called to recursively call a suspend function as the lambda, like this:
private suspend fun connectToGooglePlayBillingService(): BillingResult? {
Timber.d("connectToGooglePlayBillingService: called")
return suspendCoroutine { continuation ->
// If the billingClient is not already ready, start the connection
if (!playStoreBillingClient.isReady) {
// Start the connection and wait for its result in the listener
playStoreBillingClient.startConnection(object: BillingClientStateListener {
override fun onBillingServiceDisconnected() {
Timber.d("onBillingServiceDisconnected: called")
// Retry to connect using the RetryPolicies
RetryPolicies.connectionRetryPolicy { connectToGooglePlayBillingService() }
}
override fun onBillingSetupFinished(billingResult: BillingResult?) {
// There is code that does not matter here
}
})
}
}
}
Now, Lint tells me, that connectToGooglePlayBillingService cannot be called inside the lambda because it's a suspend function and it needs to be called inside a CoroutineScope. And as you can see, I do call the lambda inside a CoroutineScope in connectionRetryPolicy.
Is this a bug in Lint or do I do something wrong here? I know, I can create a new CoroutineScope inside the lambda and then call connectToGooglePlayBillingService and I am not sure if this is so wise, regarding performance.