-
Notifications
You must be signed in to change notification settings - Fork 260
Add support for configurable Plan Preview behavior in piped #6646
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -500,6 +500,10 @@ func (p *piped) run(ctx context.Context, input cli.Input) (runErr error) { | |
| decrypter, | ||
| cfg, | ||
| pluginRegistry, | ||
| planpreview.WithWorkerNum(cfg.PlanPreview.WorkerNum), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same reason as v0 |
||
| planpreview.WithCommandQueueBufferSize(cfg.PlanPreview.CommandQueueBufferSize), | ||
| planpreview.WithCommandCheckInterval(cfg.PlanPreview.CommandCheckInterval.Duration()), | ||
| planpreview.WithCommandHandleTimeout(cfg.PlanPreview.CommandHandleTimeout.Duration()), | ||
| planpreview.WithLogger(input.Logger), | ||
| ) | ||
| group.Go(func() error { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -79,6 +79,8 @@ type PipedSpec struct { | |
| SecretManagement *SecretManagement `json:"secretManagement,omitempty"` | ||
| // Optional settings for event watcher. | ||
| EventWatcher PipedEventWatcher `json:"eventWatcher"` | ||
| // Optional settings for plan-preview command handling. | ||
| PlanPreview PipedPlanPreview `json:"planPreview"` | ||
| // List of labels to filter all applications this piped will handle. | ||
| AppSelector map[string]string `json:"appSelector,omitempty"` | ||
| } | ||
|
|
@@ -141,6 +143,9 @@ func (s *PipedSpec) Validate() error { | |
| if err := s.EventWatcher.Validate(); err != nil { | ||
| return err | ||
| } | ||
| if err := s.PlanPreview.Validate(); err != nil { | ||
| return err | ||
| } | ||
| for _, n := range s.Notifications.Receivers { | ||
| if n.Slack != nil { | ||
| if err := n.Slack.Validate(); err != nil { | ||
|
|
@@ -1211,3 +1216,30 @@ type PipedEventWatcherGitRepo struct { | |
| // This is prioritized if both includes and this one are given. | ||
| Excludes []string `json:"excludes,omitempty"` | ||
| } | ||
|
|
||
| type PipedPlanPreview struct { | ||
| // Number of workers to handle plan-preview commands. | ||
| WorkerNum int `json:"workerNum,omitempty"` | ||
| // Channel buffer size used for plan-preview commands. | ||
| CommandQueueBufferSize int `json:"commandQueueBufferSize,omitempty"` | ||
| // Interval to fetch plan-preview commands. | ||
| CommandCheckInterval Duration `json:"commandCheckInterval,omitempty"` | ||
| // Timeout to handle each plan-preview command. | ||
| CommandHandleTimeout Duration `json:"commandHandleTimeout,omitempty"` | ||
| } | ||
|
|
||
| func (p *PipedPlanPreview) Validate() error { | ||
| if p.WorkerNum < 0 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You allow WorkerNum = 0, I scare that commands can be block by this allowance, please verify the behavior to find the right condition for validating
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I checked the handler behavior here in for i := 0; i < h.options.workerNum; i++ {
go startWorker(ctx, h.commandCh)
}From the handler logic, In the current flow, we guard this at the callsite ( I’m happy to enforce
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure the right thing to do here, but isn't that we are using defensive programming in a lot of place, I don't think this is a good idea maybe just concentrate on validating config at one place, what do you think ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I think that would be cleaner. I’ve moved the
Let me know your thoughts on this. |
||
| return errors.New("planPreview.workerNum must be greater than or equal to 0") | ||
| } | ||
| if p.CommandQueueBufferSize < 0 { | ||
| return errors.New("planPreview.commandQueueBufferSize must be greater than or equal to 0") | ||
| } | ||
| if p.CommandCheckInterval < 0 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
commandTicker := time.NewTicker(h.options.commandCheckInterval)This will cause panic if
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right, We handle this the same way as above in if cfg.PlanPreview.CommandCheckInterval > 0 {
ppOpts = append(ppOpts, planpreview.WithCommandCheckInterval(cfg.PlanPreview.CommandCheckInterval.Duration()))
} |
||
| return errors.New("planPreview.commandCheckInterval must be greater than or equal to 0") | ||
| } | ||
| if p.CommandHandleTimeout < 0 { | ||
| return errors.New("planPreview.commandHandleTimeout must be greater than or equal to 0") | ||
| } | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,8 @@ type PipedSpec struct { | |
| SecretManagement *SecretManagement `json:"secretManagement,omitempty"` | ||
| // Optional settings for event watcher. | ||
| EventWatcher PipedEventWatcher `json:"eventWatcher"` | ||
| // Optional settings for plan-preview command handling. | ||
| PlanPreview PipedPlanPreview `json:"planPreview"` | ||
| // List of labels to filter all applications this piped will handle. | ||
| AppSelector map[string]string `json:"appSelector,omitempty"` | ||
| } | ||
|
|
@@ -113,6 +115,9 @@ func (s *PipedSpec) Validate() error { | |
| if err := s.EventWatcher.Validate(); err != nil { | ||
| return err | ||
| } | ||
| if err := s.PlanPreview.Validate(); err != nil { | ||
| return err | ||
| } | ||
| for _, n := range s.Notifications.Receivers { | ||
| if n.Slack != nil { | ||
| if err := n.Slack.Validate(); err != nil { | ||
|
|
@@ -632,6 +637,33 @@ type PipedEventWatcherGitRepo struct { | |
| Excludes []string `json:"excludes,omitempty"` | ||
| } | ||
|
|
||
| type PipedPlanPreview struct { | ||
| // Number of workers to handle plan-preview commands. | ||
| WorkerNum int `json:"workerNum,omitempty"` | ||
| // Channel buffer size used for plan-preview commands. | ||
| CommandQueueBufferSize int `json:"commandQueueBufferSize,omitempty"` | ||
| // Interval to fetch plan-preview commands. | ||
| CommandCheckInterval Duration `json:"commandCheckInterval,omitempty"` | ||
| // Timeout to handle each plan-preview command. | ||
| CommandHandleTimeout Duration `json:"commandHandleTimeout,omitempty"` | ||
| } | ||
|
|
||
| func (p *PipedPlanPreview) Validate() error { | ||
| if p.WorkerNum < 0 { | ||
| return errors.New("planPreview.workerNum must be greater than or equal to 0") | ||
| } | ||
| if p.CommandQueueBufferSize < 0 { | ||
| return errors.New("planPreview.commandQueueBufferSize must be greater than or equal to 0") | ||
| } | ||
| if p.CommandCheckInterval < 0 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same reason with v0, commandCheckInterval = 0 would cause panic |
||
| return errors.New("planPreview.commandCheckInterval must be greater than or equal to 0") | ||
| } | ||
| if p.CommandHandleTimeout < 0 { | ||
| return errors.New("planPreview.commandHandleTimeout must be greater than or equal to 0") | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // PipedPlugin defines the plugin configuration for the piped. | ||
| type PipedPlugin struct { | ||
| // The name of the plugin. | ||
|
|
||
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.
IMO, this is dangerous, I would think a safer approach is checking whether these values from
PlanPreviewoptions are not zero value first: if it != 0, then add the optionFor example
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.
ahh, good one. Yeah, how about I frame it like this, does it seem right now:
Uh oh!
There was an error while loading. Please reload this page.
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.
it seems like a good approach now, i think you should verify whether
CommandQueueBufferSize = 0is valid. Go has buffer size = 0 for channel right ^ ^, maybe this case can be similarThere 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.
Yeah I checked this, since we do
make(chan ..., commandQueueBufferSize)in the handler,make(chan T, 0)is valid in Go (unbuffered), soCommandQueueBufferSize = 0itself wouldn’t break anything.in
pkg/app/piped/planpreview/handler.go:The tricky part is config: since it’s a plain
int, omitted and0both become0after decode. So if we pass0through, even “not set” would behave like unbuffered instead of using the default (10), which might be unexpected.Right now with the
> 0guard, both cases just fall back to the default, which I felt safer.If we want to support unbuffered explicitly, we’d probably need a way to distinguish omitted vs 0.
What do you think, should we support that, or keep default-only for now?