-
Notifications
You must be signed in to change notification settings - Fork 26
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 multiple update selectors #383
base: main
Are you sure you want to change the base?
Conversation
3be85ec
to
e9c2100
Compare
ae5affa
to
fae9001
Compare
a6175c8
to
06fd1a8
Compare
Please rebase on the main branch since #387 is merged — which have couple of new stages in the flows |
// UpdateSelectorEverything means that all components could be updated. | ||
// With this setting and if master or tablet nodes need update all the components would be updated. | ||
UpdateSelectorEverything UpdateSelector = "Everything" | ||
) |
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.
Let's not remove updateSelector
stuff for now. We are shooting ourselves in the leg that way, since we ourselves need some time to migrate from updateSelector
to updateSelectors
.
Let's just add deprecation comment and remove it it next releases when we migrate.
I suggest we have some function, which would receive ytsaurus spec and return updateSelectors
values.
It should be easy to unittest it for all major cases, which are:
- if
updateSelectors
is not nil/empty list — we return it as is - if
updateSelectors
is nil/empty list andupdateSelector != UpdateSelectorUnspecified
— we convert it's value to theupdateSelectors
value. Rules are:
UpdateSelectorNothing > []ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupNone}}
UpdateSelectorStatelessOnly > []ComponentUpdateSelector{{ComponentGroup: consts. ComponentGroupStateless}}
UpdateSelectorEverything > []ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupEverything}}
UpdateSelectorMasterOnly > []ComponentUpdateSelector{{ComponentType: consts.MasterType}}
UpdateSelectorDataNodesOnly > []ComponentUpdateSelector{{ComponentType: consts.DataNodes}}
UpdateSelectorExecNodesOnly > []ComponentUpdateSelector{{ComponentType: consts.ExecNodes}}
UpdateSelectorTabletNodesOnly > []ComponentUpdateSelector{{ComponentType: consts.TabletNodes}}
- if
updateSelectors
is nil/empty list andupdateSelector == UpdateSelectorUnspecified
we convertenableFullUpdate
to theupdateSelectors
value. Rules are:
enableFullUpdate=true > []ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupEverything}}
enableFullUpdate=false => []ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupStateless}}
return ytv1.UpdateFlowFull | ||
} | ||
return ytv1.UpdateFlowStateless | ||
} |
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.
Since we have combination of selectors that wouldn't be possible to cover with existing flow (like like master+http proxies
will go to everything and will update tablet nodes which wasn't allowed by selector) we have to make changes in flows code.
Also we've discovered that we already have checks like needSchedulerUpdate
and needQueryTrackerUpdate
we simplify code a bit and just have one "EverythingFlow" with added if
s for the master and tablet nodes in the required places. Other flows and flow field itself can be removed with this change — that would make less copypaste and possible errors in the code.
The thing which is bothers me that this flows is not test covered very well and it is rather expensive (in the meaning of test time and code amount) to test all the required cases in e2e.
So I suggest we convert this flows code with switch-cases in a different shape. We introduce some struct like this
type flowStep struct {
name string
condition func(ytv1.Ytsaurus) bool
onSuccess func() err
}
and have some function to build flow from the list of exact components which require update
func buildFlow(components) []flowStep{
var steps []flowStep
if components.Contain(masterType) {
steps = append(flowStep{
name: "safe mode enabled",
condition: func(ytsaurus ytv1.Ytsaurus) {
return resource.Status.UpdateStatus.State == `ytv1.UpdateStateWaitingForSafeModeEnabled`
},
onSuccess: func(ytsaurus ytv1.Ytsaurus) {
return ytsaurus.SaveUpdateState(ctx, ytv1.UpdateStateWaitingForTabletCellsSaving)
}
})
}
...
return steps
}
(I'm not sure that this exact fields and functions should be there, but something similar should work).
That way we can cover our flow building with fast unittest good enough and cover all the important cases and be sure not to break stuff in flow logic.
So the whole code for this PR will look like this:
- convert fullUpdate+updateSelector+updateSelectors to the updateSelectors list
- get components which require update and filter them with updateSelectors — set it to the updating components field of UpdateState and set state=Updating
- generate flow for the list of the componenents
- apply the flow
all 1-3 steps can be untitested that way.
I think it is better to do it in the separate PR and after that use that code in this PR.
What do you think? Does it make sense to you?
935eb92
to
39016b9
Compare
39016b9
to
683a5b9
Compare
No description provided.