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

Add schedule API #943

Merged
merged 8 commits into from
Nov 9, 2022
Merged

Conversation

Quinn-With-Two-Ns
Copy link
Contributor

What was changed

Add schedule API

Why?

Checklist

  1. Closes High level API for schedules #871

  2. How was this tested:

  1. Any docs updates needed?

internal/client.go Outdated Show resolved Hide resolved
WorkflowType WorkflowType

// Args - Arguments of the workflow
Args *commonpb.Payloads
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cretz we talked about using encoded values for the description of the workflow arguments but I found they couldn't be converted back to payload for the Update function.

Copy link
Member

Choose a reason for hiding this comment

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

This is probably fine. I would have also supported a new concept called *converter.RawValue or something that carried the payload and data converter, but that may be a bit much.

internal/client.go Outdated Show resolved Hide resolved
}

// ScheduleUpdate describes the desired new schedule from ScheduleHandle.Update.
ScheduleUpdate struct {
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 added another struct around Schedule incase we wanted to allow updating other parts of a schedule in the future. I was specifically thinking the Memo and SearchAttributes

}

// ScheduleUpdateOptions configure the parameters for updating a schedule.
ScheduleUpdateOptions struct{}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is empty right now because the server does not return a failure on conflict token mismatch. Once that is fixed we can add an option to fail on that case and retry.

internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
Action ScheduleAction

// Schedule - Describes when Actions should be taken.
Spec *ScheduleSpec
Copy link
Member

Choose a reason for hiding this comment

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

just curious, why pointers for some and not others?

Copy link
Member

Choose a reason for hiding this comment

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

If you mean "why not a pointer for Action", that is because it is an interface

internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/client.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
internal/interceptor.go Outdated Show resolved Hide resolved
internal/interceptor.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
internal/internal_workflow_client.go Outdated Show resolved Hide resolved
test/integration_test.go Show resolved Hide resolved
// Start span and write to header
span, ctx, err := t.root.startSpanFromContext(ctx, &TracerStartSpanOptions{
Operation: "CreateSchedule",
Name: in.Options.ID,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

schedules don't really have a concept of a name so I used the ID.

return recentActions
}

func encodeScheduleWorklowArgs(dc converter.DataConverter, args []interface{}) (*commonpb.Payloads, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cretz I did consider modifying the existing functions instead of creating new ones, but I didn't want to leak this visible change out of the experimental API

func encodeScheduleWorklowArgs(dc converter.DataConverter, args []interface{}) (*commonpb.Payloads, error) {
payloads := make([]*commonpb.Payload, len(args))
for i, arg := range args {
// arg is already encoded
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 support a mix of serialized and not serialized Args. I found it was nice when writing integration tests.

Copy link
Member

@cretz cretz Nov 8, 2022

Choose a reason for hiding this comment

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

This is probably ok, but technically this is a bit different than elsewhere where we'd call DataConverter.ToPayloads (plural) w/ all args if they wanted to, say, condense them or something. But most people treat that as the same as calling each individually. And I think we're inconsistent here anyways. So you're good.

You may want to document on args, search attributes, and memos that we just pass through payloads on create/update.

payloads := make([]*commonpb.Payload, len(args))
for i, arg := range args {
// arg is already encoded
if enc, ok := arg.(*commonpb.Payload); ok {
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 chose to use *commonpb.Payload here instead of EncodedValues because it limited the amount of possible user error, was consistent with current memo and search attribute usage in other parts of the SDK

Copy link
Member

Choose a reason for hiding this comment

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

That's a fairly recent change to make those that way IIRC, but I'm fine w/ it.

@Quinn-With-Two-Ns Quinn-With-Two-Ns marked this pull request as ready for review November 8, 2022 21:18
@Quinn-With-Two-Ns Quinn-With-Two-Ns requested a review from a team as a code owner November 8, 2022 21:18
State: &schedulepb.ScheduleState{
Notes: in.Options.Note,
Paused: in.Options.Paused,
LimitedActions: in.Options.RemainingActions != 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

In describe and update, the value of RemainingActions has to be interpreted in regard of LimitedActions. Assuming LimitedActions == true, then RemainingActions == 0 would indicate that the schedule can't happens anymore (ie. it is implicitely paused), until remainingActions is reset to a non zero value.

Having only RemainingActions in create might make this semantic harder to understand for users. I'd suggest either adding LimitedActions to create options, or using a value other than 0 (ie -1) for "don't limit on action count", and using that same semantic in Describe and Update.

@Quinn-With-Two-Ns Quinn-With-Two-Ns merged commit 8ab62d9 into temporalio:master Nov 9, 2022
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.

High level API for schedules
4 participants