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

feat: add retry directive #1552

Merged
merged 4 commits into from
May 22, 2024
Merged

feat: add retry directive #1552

merged 4 commits into from
May 22, 2024

Conversation

matt2e
Copy link
Collaborator

@matt2e matt2e commented May 22, 2024

adds retry directive for fsm transition verbs. This PR does not contain logic to execute retries.

  • go expects format //ftl:retry [count] minbackoff [maxbackoff]
  • schema has format +retry [count] minbackoff [maxbackoff]
  • backoffs support s, m, h, d units like 90s or 1m30s
  • validation makes sure retry directive is only added to verbs that are part of a FSM within the same module
  • min/max backoffs are 1s/1d (very debatable...)

@matt2e matt2e requested a review from alecthomas as a code owner May 22, 2024 04:50
@matt2e matt2e requested review from a team and wesbillman and removed request for a team May 22, 2024 04:50
@ftl-robot ftl-robot mentioned this pull request May 22, 2024
schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema"
)

const (
Copy link
Collaborator Author

@matt2e matt2e May 22, 2024

Choose a reason for hiding this comment

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

String constants are just to make error printing have the same format we expect users to use (ie 1d not go's standard 24h0m0s)

}
}
`,
errs: []string{
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Please read these to see if they are clear

@matt2e matt2e force-pushed the matt2e/retry-directives branch 2 times, most recently from 8398f38 to 2196d1d Compare May 22, 2024 05:10

Count *int `parser:"'+' 'retry' (@Number Whitespace)?" protobuf:"2,optional"`
MinBackoff string `parser:"@(Number Ident)?" protobuf:"3"`
MaxBackoff string `parser:"@(Number Ident)?" protobuf:"4"`
Copy link
Collaborator Author

@matt2e matt2e May 22, 2024

Choose a reason for hiding this comment

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

FYI, the reasoning behind @(Number Ident)? is that I could not find a sane way to parse multiple number + unit pairs while ensuring no whitespace inbetween
Also, 1m30s is tokenized as 1 (number) + m30s (ident).

Instead we are just getting these in as strings and then parsing them ourselves using regex. This helps us customize the error messages for more cases.

Copy link
Collaborator

@alecthomas alecthomas left a comment

Choose a reason for hiding this comment

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

Nice nice. Will we add FSM-wide retries (ie. a retry annotation on the FSM itself) in a future PR?

count := int64(*m.Count)
return &schemapb.MetadataRetry{
Pos: posToProto(m.Pos),
Count: &count,
Copy link
Collaborator

Choose a reason for hiding this comment

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

You should be able to use proto.Int64(int64(m.Count)) here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, looks like i made a more fundamental mistake... not handling m.Count == 0
Updated to

var count *int64
if m.Count != nil {
  count = proto.Int64(int64(*m.Count))
}

backend/schema/metadataretry.go Outdated Show resolved Hide resolved
backend/schema/metadataretry.go Outdated Show resolved Hide resolved
backend/schema/metadataretry.go Outdated Show resolved Hide resolved
backend/schema/validate.go Outdated Show resolved Hide resolved
merr = append(merr, errorf(md, "verb %s: %v", n.Name, err))
return
}
if maxDuration, ok := maxDuration.Get(); ok && maxDuration < minDuration {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should there be a check against MaxBackoffDuration (ie. 24h)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Both MinBackoff and MaxBackoff are checked for min/max during parseRetryDuration

`25:7-7: verb K: retry count must be atleast 1`,
`4:7-7: verb A: retry has unit "m" out of order. Units need to be ordered from largest to smallest`,
`6:7-7: verb B: retry has unit "d" out of order. Units need to be ordered from largest to smallest`,
`8:7-7: verb C: retry must have a minimum backoff of 1s`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice

go-runtime/compile/parser.go Outdated Show resolved Hide resolved
@matt2e matt2e force-pushed the matt2e/retry-directives branch from a542225 to 111b0ff Compare May 22, 2024 06:03
@matt2e matt2e merged commit ac5c6ff into main May 22, 2024
24 checks passed
@matt2e matt2e deleted the matt2e/retry-directives branch May 22, 2024 06:08
@matt2e matt2e mentioned this pull request May 24, 2024
3 tasks
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.

2 participants