dave08
10/06/2024, 1:49 PMAlejandro Serrano.Mena
10/06/2024, 6:32 PMdave08
10/07/2024, 9:26 AMdave08
10/07/2024, 9:27 AMAlejandro Serrano.Mena
10/07/2024, 9:27 AMdave08
10/07/2024, 9:29 AMdave08
10/07/2024, 9:35 AMerror: cannot access SearchSuggestionsViewModel
public abstract ViewModel binds(SearchSuggestionsViewModel vm);
^
bad class file: /home/.../app/build/tmp/kotlin-classes/debug/.../searchScreens/SearchSuggestionsViewModel.class
undeclared type variable: Input
Please remove or make sure it appears in the correct subdirectory of the classpath.
dave08
10/07/2024, 9:37 AMdave08
10/07/2024, 9:39 AMprivate val recur2 = Schedule.recurs<CallError>(3)
...
recur2.retryEither {
searchApi.getSuggestions(...) // returns an Either<CallError, List<String>>
}
Alejandro Serrano.Mena
10/07/2024, 9:42 AMdave08
10/07/2024, 9:45 AMAlejandro Serrano.Mena
10/07/2024, 9:45 AMdave08
10/07/2024, 9:45 AMAlejandro Serrano.Mena
10/07/2024, 9:46 AMretryEither
?dave08
10/07/2024, 9:47 AMprivate val recur2 = Schedule.recurs<CallError>(3)
in the code causes the error 😵💫...dave08
10/07/2024, 9:49 AMdave08
10/07/2024, 10:00 AMAlejandro Serrano.Mena
10/07/2024, 10:01 AMSchedule
in the extension funcion to coincide exactly with those of the original Schedule
definitiondave08
10/07/2024, 10:02 AMdave08
10/07/2024, 10:06 AMAlejandro Serrano.Mena
10/07/2024, 10:09 AMError
, name that type parameter Input
(this is the original name in Schedule<Input, Output>
)dave08
10/07/2024, 10:12 AM/**
* Retries [action] using any [Throwable] that occurred as the input to the [Schedule].
* It will throw the last exception if the [Schedule] is exhausted, and ignores the output of the [Schedule].
*/
public suspend fun <A> Schedule<Throwable, *>.retry(action: suspend () -> A): A =
retryOrElse(action) { e, _ -> throw e }
/**
* Retries [action] using any [Throwable] that occurred as the input to the [Schedule].
* If the [Schedule] is exhausted,
* it will invoke [orElse] with the last exception and the output of the [Schedule] to produce a fallback [Input] value.
*/
public suspend fun <Input, Output> Schedule<Throwable, Output>.retryOrElse(
action: suspend () -> Input,
orElse: suspend (Throwable, Output) -> Input
): Input = retryOrElseEither(action, orElse).merge()
/**
* Retries [action] using any [Throwable] that occurred as the input to the [Schedule].
* If the [Schedule] is exhausted,
* it will invoke [orElse] with the last exception and the output of the [Schedule] to produce a fallback value of [A].
* Returns [Either] with the fallback value if the [Schedule] is exhausted, or the successful result of [action].
*/
public suspend fun <Input, Output, A> Schedule<Throwable, Output>.retryOrElseEither(
action: suspend () -> Input,
orElse: suspend (Throwable, Output) -> A
): Either<A, Input> {
var step: ScheduleStep<Throwable, Output> = step
while (true) {
currentCoroutineContext().ensureActive()
try {
return Either.Right(action.invoke())
} catch (e: Throwable) {
when (val decision = step(e)) {
is Continue -> {
if (decision.delay != ZERO) delay(decision.delay)
step = decision.step
}
is Done -> return Either.Left(orElse(e.nonFatalOrThrow(), decision.output))
}
}
}
}
/**
* Retries [action] using any [Error] that occurred as the input to the [Schedule].
* It will return the last [Error] if the [Schedule] is exhausted, and ignores the output of the [Schedule].
*/
public suspend inline fun <Input, Result, Output> Schedule<Input, Output>.retryRaise(
@BuilderInference action: Raise<Input>.() -> Result,
): Either<Input, Result> = either {
retry(this@retryRaise, action)
}
/**
* Retries [action] using any [Error] that occurred as the input to the [Schedule].
* It will return the last [Error] if the [Schedule] is exhausted, and ignores the output of the [Schedule].
*/
public suspend inline fun <Input, Result, Output> Schedule<Input, Output>.retryEither(
@BuilderInference action: () -> Either<Input, Result>,
): Either<Input, Result> = retryRaise {
action().bind()
}
/**
* Retries [action] using any [Error] that occurred as the input to the [Schedule].
* It will return the last [Error] if the [Schedule] is exhausted, and ignores the output of the [Schedule].
*/
public suspend inline fun <Input, Result, Output> Raise<Input>.retry(
schedule: Schedule<Input, Output>,
@BuilderInference action: Raise<Input>.() -> Result,
): Result {
var step: ScheduleStep<Input, Output> = schedule.step
while (true) {
currentCoroutineContext().ensureActive()
fold(
action,
recover = { error ->
when (val decision = step(error)) {
is Continue -> {
if (decision.delay != ZERO) delay(decision.delay)
step = decision.step
}
is Done -> raise(error)
}
},
transform = { result ->
return result
},
)
}
}
Alejandro Serrano.Mena
10/07/2024, 10:13 AMInput
type parameters in the functions where they are not used?dave08
10/07/2024, 10:15 AMdave08
10/07/2024, 10:16 AM@JvmInline
public value class Schedule<in Input, out Output>(public val step: ScheduleStep<Input, Output>)
dave08
10/07/2024, 11:24 AMdave08
10/07/2024, 11:32 AMdave08
10/07/2024, 11:48 AMvalue
and @JvmInline
and it works...dave08
10/07/2024, 12:26 PMAlejandro Serrano.Mena
10/07/2024, 1:01 PM