-
Notifications
You must be signed in to change notification settings - Fork 47
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
[data] anchored and jittered schedules #919
Conversation
eab31e5
to
d612420
Compare
effect.delayed(delay).andThen(Loop.continue(nextSchedule)) | ||
}.getOrElse { | ||
effect.map(Loop.done) | ||
Clock.now.map { now => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it useful to fetch the clock once outside the loop to avoid pulling from the local multiple times?
case Absent => Loop.done(state) | ||
case Present((duration, nextSchedule)) => | ||
clock.sleep(duration).map(_.use(_ => f(state).map(Loop.continue(_, nextSchedule)))) | ||
Clock.now.map { now => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use lowercase clock
?
case Present((duration, nextSchedule)) => | ||
val nextExecution = lastExecution + duration | ||
clock.sleep(duration).map(_.use(_ => f(state).map(Loop.continue(nextExecution, _, nextSchedule)))) | ||
Clock.now.map { now => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lowercase clock?
for | ||
(d1, s1) <- a.next | ||
(d2, s2) <- b.next | ||
(d1, s1) <- a.next(now) | ||
(d2, s2) <- b.next(now) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pre-existing: I think this should be a fold
- otherwise you may end up discarding when one schedule produces a next.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was the intended behavior considering that the delay of a done schedule is essentially Instant.Max
. The Min
implementation does what you mentioned
I'm working on STM optimizations and want to use a jittered schedule to reduce the impact of retry storms. Since we avoid side effects in
kyo-data
, I'm passing the currentInstant
toschedule.next
and calculating the jitter deterministically via hashing. It isn't random but, given thatInstant
has nanosecond precision, it seems reasonable.We could pass a random number from
kyo-core
instead but we'd need to eventually pass the instant anyway to implement more advanced schedules like the newSchedule.anchored
I've also added in this PR.