-
Notifications
You must be signed in to change notification settings - Fork 4
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
Feature/state machine changes #454
Conversation
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.
Have added a few thoughts on the structure.
application/orchestrator.go
Outdated
//nolint:gosec // This is not a hardcoded credential. | ||
downloadServiceToken = "X-Download-Service-Token" |
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.
Would the following address the lint error without need for the comment? (haven't tested it, so just a theory)
//nolint:gosec // This is not a hardcoded credential. | |
downloadServiceToken = "X-Download-Service-Token" | |
//nolint:gosec // This is not a hardcoded credential. | |
downloadServiceTokenHeader = "X-Download-Service-Token" |
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.
I'll address this in the overall PR for this change.
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.
Shaping up nicely. I think this will definitely improve readability and maintainability immensely. Have left some thoughts and comments.
application/orchestrator.go
Outdated
return nil | ||
} | ||
|
||
func castStateToState(state string) State { |
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 looks like this could be handled by the state machine itself as it has the map[string]State
state map so can complete this cast internally. See comment on Transition
function.
application/orchestrator.go
Outdated
if vars[hasDownloads] != trueStringified { | ||
data["updated_state"] = versionUpdate.State | ||
if versionUpdate.State == models.PublishedState { | ||
if err := smDS.publishVersion(ctx, currentDataset, currentVersion, versionUpdate, versionDetails); err != nil { | ||
log.Error(ctx, "putVersion endpoint: failed publishing version", err) | ||
return err | ||
} | ||
} | ||
|
||
if versionUpdate.State == models.AssociatedState && currentVersion.State != models.AssociatedState { | ||
|
||
if err := smDS.associateVersion(ctx, currentVersion, versionUpdate, versionDetails); err != nil { | ||
log.Error(ctx, "putVersion endpoint: failed associating version", err) | ||
return err | ||
} | ||
} | ||
} |
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.
This logic should form part of the transition into published
and associated
states respectively and should therefore be called from the Enter
functions of those states.
Is the thinking is to complete the refactor in two steps to minimise the scope of refactoring in a single PR?
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.
This has been moved in to the enter function, let me know if this looks right to you, if it is I'll implement for the associateVersion also.
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.
One comment about the locking, but looks right to me.
application/state_machine.go
Outdated
for i := 0; i < len(transitions); i++ { | ||
if previousState == transitions[i] { | ||
match = true | ||
nextState = castStateToState(newState) |
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.
This call to the hard coded cast in the castStateToState()
could be replaced with:
nextState = castStateToState(newState) | |
nextState = sm.states[newState] |
This would improve the maintainability of the code by preventing the need to extend the hard coded cast when changing the states.
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.
This has been amended
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.
I am not seeing this change. Maybe it hasn't been pushed?
application/application.go
Outdated
fmt.Println("Validation Failed") | ||
fmt.Println(errModel) | ||
return errModel | ||
} else { |
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.
else
is redundant here as the above will have returned on error.
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.
This has now been removed
application/application.go
Outdated
lockID, error := smDS.DataStore.Backend.AcquireInstanceLock(ctx, currentVersion.ID) | ||
if error != nil { | ||
return error | ||
} | ||
defer func() { | ||
smDS.DataStore.Backend.UnlockInstance(ctx, lockID) | ||
}() |
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.
I think we may need to move the locking to the orchestrator outside of the enter function (e.g. call it in the the AmendVersion function) so that the lock is acquired before the current version data is read to prevent a race condition. This will also mean that the lock will be implemented across the different transitions.
It looks like we might need to consider a dataset level lock as well, but as I don't believe that currently exists it is a later concern.
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.
I have now moved where the lock happens
application/application.go
Outdated
} | ||
|
||
// This is only applicable to CMD datasets | ||
if currentVersion.Type == "v4" { |
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 appears that CMD could have multiple string values here. Suggest calling
dp-dataset-api/models/dataset.go
Lines 54 to 57 in d562530
func GetDatasetType(datasetType string) (DatasetType, error) { | |
switch datasetType { | |
case "filterable", "v4", "": | |
return Filterable, nil |
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.
This check has now been amended
application/orchestrator.go
Outdated
if vars[hasDownloads] != trueStringified { | ||
data["updated_state"] = versionUpdate.State | ||
if versionUpdate.State == models.PublishedState { | ||
if err := smDS.publishVersion(ctx, currentDataset, currentVersion, versionUpdate, versionDetails); err != nil { | ||
log.Error(ctx, "putVersion endpoint: failed publishing version", err) | ||
return err | ||
} | ||
} | ||
|
||
if versionUpdate.State == models.AssociatedState && currentVersion.State != models.AssociatedState { | ||
|
||
if err := smDS.associateVersion(ctx, currentVersion, versionUpdate, versionDetails); err != nil { | ||
log.Error(ctx, "putVersion endpoint: failed associating version", err) | ||
return err | ||
} | ||
} | ||
} |
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.
One comment about the locking, but looks right to me.
return nil | ||
} | ||
|
||
func UpdateVersionInfo(smDS *StateMachineDatasetAPI, ctx context.Context, |
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.
Consider whether this needs to be exported.
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.
I've now amended this
if err := generator.Generate(ctx, versionDetails.datasetID, versionUpdate.ID, versionDetails.edition, versionDetails.version); err != nil { | ||
data["instance_id"] = versionUpdate.ID | ||
data["state"] = versionUpdate.State | ||
data["type"] = t.String() | ||
log.Error(ctx, "State Machine: Publish: PublishDataset: error while attempting to generate full dataset version downloads on version publish", err, data) | ||
return err | ||
// TODO - TECH DEBT - need to add an error event for this. Kafka message perhaps. | ||
} | ||
log.Info(ctx, "State Machine: Publish: PublishDataset: generated full dataset version downloads:", data) |
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.
Need to check that generator is not nil. Something like:
if err := generator.Generate(ctx, versionDetails.datasetID, versionUpdate.ID, versionDetails.edition, versionDetails.version); err != nil { | |
data["instance_id"] = versionUpdate.ID | |
data["state"] = versionUpdate.State | |
data["type"] = t.String() | |
log.Error(ctx, "State Machine: Publish: PublishDataset: error while attempting to generate full dataset version downloads on version publish", err, data) | |
return err | |
// TODO - TECH DEBT - need to add an error event for this. Kafka message perhaps. | |
} | |
log.Info(ctx, "State Machine: Publish: PublishDataset: generated full dataset version downloads:", data) | |
if generator == nil { | |
log.Info(ctx, "PublishDataset: no download generation needed for dataset type", data) | |
} else { | |
if err := generator.Generate(ctx, versionDetails.datasetID, versionUpdate.ID, versionDetails.edition, versionDetails.version); err != nil { | |
data["instance_id"] = versionUpdate.ID | |
data["state"] = versionUpdate.State | |
data["type"] = t.String() | |
log.Error(ctx, "State Machine: Publish: PublishDataset: error while attempting to generate full dataset version downloads on version publish", err, data) | |
return err | |
// TODO - TECH DEBT - need to add an error event for this. Kafka message perhaps. | |
} | |
log.Info(ctx, "State Machine: Publish: PublishDataset: generated full dataset version downloads:", data) | |
} |
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.
The nil check has now been added
application/state_machine.go
Outdated
nextState = castStateToState(versionUpdate.State) | ||
if nextState == nil { | ||
return errors.New("incorrect state value") | ||
} |
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.
This function call can be simplified as something like:
nextState = castStateToState(versionUpdate.State) | |
if nextState == nil { | |
return errors.New("incorrect state value") | |
} | |
nextState, ok = castStateToState(versionUpdate.State) | |
if !ok { | |
return errors.New("incorrect state value") | |
} |
Thereby removing the need for a hard coded cast function.
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.
This has now been amended
// lockID, error := smDS.DataStore.Backend.AcquireInstanceLock(ctx, currentVersion.ID) | ||
// if error != nil { | ||
// return error | ||
// } | ||
// defer func() { | ||
// smDS.DataStore.Backend.UnlockInstance(ctx, lockID) | ||
// }() |
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.
A little tidy up needed
Closing this PR - new one to follow once unit tests and component tests are fixed. |
What
Draft PR for state machine implementation. Tests have not been updated yet.
How to review
Ensure the changes make sense.
Who can review
@janderson2