-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a schedule-aware repeat #57
Comments
Some operations that we'd like to have:
Should we measure time between start of each operation (start2-start1), or the pause between operation invocations (start2-end1)? Or maybe this should be configurable? |
I did some API prototypic which led to few observations:
def schedule[T](
schedule: Schedule,
onTick: (Int, Either[Throwable, T]) => Unit = (_: Int, _: Either[Throwable, T]) => (),
shouldRetryOnError: Throwable => Boolean = (_: Throwable) => false,
shouldContinue: T => Boolean = (_: T) => true
)(operation: => T): T =
scheduleEither(schedule, onTick, shouldRetryOnError, shouldContinue)(Try(operation).toEither).fold(throw _, identity)
def scheduleEither[E, T](
schedule: Schedule,
onTick: (Int, Either[E, T]) => Unit = (_: Int, _: Either[E, T]) => (),
shouldRetryOnError: E => Boolean = (_: E) => false,
shouldContinue: T => Boolean = (_: T) => true
)(operation: => Either[E, T]): Either[E, T] =
scheduleWithErrorMode(EitherMode[E])(schedule, onTick, shouldRetryOnError, shouldContinue)(operation)
def scheduleWithErrorMode[E, F[_], T](em: ErrorMode[E, F])(
schedule: Schedule,
onTick: (Int, Either[E, T]) => Unit = (_: Int, _: Either[E, T]) => (),
shouldRetryOnError: E => Boolean = (_: E) => false,
shouldContinue: T => Boolean = (_: T) => true
)(operation: => F[T]): F[T] = ... Then def retryWithErrorMode[E, F[_], T](em: ErrorMode[E, F])(policy: RetryPolicy[E, T])(operation: => F[T]): F[T] =
scheduleWithErrorMode(em)(
policy.schedule,
policy.onRetry,
policy.resultPolicy.isWorthRetrying,
t => !policy.resultPolicy.isSuccess(t)
)(operation)
See #172 |
I still think
The difference is that for So with the definition of "success" and "error" being user-provided (in the form of a function: I think the
What we could have is use-case-specific DSLs for retries & repeats, using retry or repeat-specific vocabulary for naming the constructor methods, but under the covers yield Another thing to consider: it might be useful to linearly combine schedules. Each schedule would have to be combined with the number of repetitions it handles (0, 1, 2, ... infinity). Then, we might want to say: run |
I wanted to distinguish these two options by putting them into separate
Also, for now I created |
I think both delay strategies can be useful in both situations (repeat/retry). So ideally we want to be able to use both. |
By design all the strategies can be used in |
Right, in case maybe it would make sense to parametrise all of |
enum DelayPolicy:
case SinceTheStartOfTheLastInvocation, SinceTheEndOfTheLastInvocation |
While the retry mechanism allows for repeating an operation - according to a
Schedule
in case of error, we'd also like to have a schedule-awarerepeat
, which would run an operation according to aSchedule
or perhaps until a stop condition is met.Some things to consider:
repeat
andretry
?Schedule
likeUntilResult[T](p: T => Boolean)
orUntil(p: => Boolean)
, or both?The text was updated successfully, but these errors were encountered: