Skip to content
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

Introduce TimerKind to support different types of timers #1480

Merged
merged 7 commits into from
Apr 30, 2024

Conversation

tillrohrmann
Copy link
Contributor

@tillrohrmann tillrohrmann commented Apr 29, 2024

The TimerKind is used to store differently typed timers. Currently,
we support journal scoped timers that are scoped to a certain journal
entry. Additionally, we support invocation scoped timers that are scoped
to an invocation (e.g. only a single timer for a given wake up time for
a given invocation can exist).

This fixes #1417.

Only the commits starting from 6ab9fdf are relevant for this PR.

Copy link
Contributor

@slinkydeveloper slinkydeveloper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need an ad-hoc kind for every type of timer we can register.

Comment on lines 67 to 70
timer_key: TimerKey::new_invocation(
wake_up_time.as_u64(),
invocation_id.invocation_uuid(),
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be another timer kind, specific for the action of cleaning invocation status. Imagine we'll be able to support later cleaning up at separate times the invocation status and the idempotency key.

Copy link
Contributor Author

@tillrohrmann tillrohrmann Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you are describing should already be supported. The one thing that is not supported is to have multiple actions scheduled at the same time for a single invocation because they would have the same key. Currently, we don't have this requirement. Once we have it, then we can introduce a new TimerKind for the concurrent action.

Maybe I should have called TimerKind TimerScope instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the argument one could make is that having a TimerKind per Timer would establish a one to one mapping between these two types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the argument one could make is that having a TimerKind per Timer would establish a one to one mapping between these two types.

Yes this is also true, i think it is overall simpler to understand.

The one thing that is not supported is to have multiple actions scheduled at the same time for a single invocation because they would have the same key. Currently, we don't have this requirement. Once we have it, then we can introduce a new TimerKind for the concurrent action.

Not yet, but as described above, we already have some ideas in mind where multiple timers with same scope would be required, so I think it makes sense from now to support that.

// without converting to i64 this field will encode as a string
// however, overflowing i64 seems unlikely
restate.internal.end_time = i64::try_from(timer_value.wake_up_time().as_u64()).expect("wake up time should fit into i64"),
);

debug_if_leader!(
is_leader,
restate.timer.key = %TimerKeyDisplay(timer_value.key()),
restate.journal.index = entry_index,
restate.invocation.id = %invocation_id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary repetition I think, you have the invocation id in the span already

Copy link
Contributor Author

@tillrohrmann tillrohrmann Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, then I'll remove it. I was assuming it is needed because the info_span_if_leader contained it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of other effects still have the restate.invocation.id as an event attribute. What is the guiding principle here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When there is a caller and callee, you put the callee invocation id too in the event itself and not the span.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When there is a caller and callee, you put the callee invocation id too in the event itself and not the span.

I assume that for SetState there is no callee, right? It seems that we are still logging restate.invocation.id. Could it be that we didn't properly clean it up after the latest changes to the how the span is initialized?

crates/worker/src/partition/state_machine/effects.rs Outdated Show resolved Hide resolved
@tillrohrmann
Copy link
Contributor Author

I think we need an ad-hoc kind for every type of timer we can register.

Thanks for your review @slinkydeveloper. Could you elaborate on why you think that we need ad-hoc kinds for every type of timer we can register? From your comments, it was not fully clear to me yet.

@tillrohrmann
Copy link
Contributor Author

I've pushed an additional commit that introduces for every timer type its own kind.

Copy link
Contributor

@slinkydeveloper slinkydeveloper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this! Can't wait to add new timers now :)

crates/storage-api/src/timer_table/mod.rs Show resolved Hide resolved
@tillrohrmann
Copy link
Contributor Author

Thanks for the review @slinkydeveloper. Merging this PR now.

This commit changes how we store the InvocationId in the partition storage
from a custom encoding to using Protobuf. Thereby, we will be able to evolve
the InvocationId in the future if needed.

This fixes restatedev#1478.
This commit makes the Timer::CompleteSleepEntry contain the full InvocationId
and the journal entry index to make it self-contained. This simplifies the change
of the TimerKey in a follow-up commit.
The TimerKey struct now directly implements the TimerKey trait used by
the timer service.
The TimerKind is used to store differently typed timers. Currently,
we support journal scoped timers that are scoped to a certain journal
entry. Additionally, we support invocation scoped timers that are scoped
to an invocation (e.g. only a single timer for a given wake up time for
a given invocation can exist).

This fixes restatedev#1417.
This commit introduces factory methods on the Timer which creates the right
timer kind and corresponding timer key. This prevents the accidental mixup
of Timers with their keys.
@tillrohrmann tillrohrmann merged commit 6ea99f1 into restatedev:main Apr 30, 2024
5 checks passed
@tillrohrmann tillrohrmann deleted the issues/1417 branch April 30, 2024 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update Timers table key to work for different types of timers
2 participants