-
Notifications
You must be signed in to change notification settings - Fork 128
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
GetVersion implementation #182
Conversation
internal_event_handlers.go
Outdated
if attributes.GetMarkerName() != sideEffectMarkerName { | ||
switch attributes.GetMarkerName() { | ||
case sideEffectMarkerName: | ||
dec := gob.NewDecoder(bytes.NewBuffer(attributes.GetDetails())) |
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.
NIT: Could would be more readable if you extract the decoding into a helper method. (Same comment for decoding the "version marker"
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.
Why are you not using encoding interface on hostEnv to decode, so we can switch easily with a different encoder.
internal_decision_state_machine.go
Outdated
markerID := fmt.Sprintf("%v_%v", versionMarkerName, changeID) | ||
var buf bytes.Buffer | ||
enc := gob.NewEncoder(&buf) | ||
if err := enc.Encode(changeID); err != 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.
Why are you not going through encoding interface exposed through hostEnv.Encoder()? that would give us single place to switch different encoders.
internal_event_handlers.go
Outdated
if version > maxSupported { | ||
panic(fmt.Sprintf("Workflow code is too old to support version %v "+ | ||
"for \"%v\" changeID. The maximum supported version is %v", | ||
version, changeID, minSupported)) |
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.
minSupported -> maxSupported
@@ -335,6 +335,40 @@ func (wc *workflowEnvironmentImpl) RequestCancelTimer(timerID string) { | |||
wc.logger.Debug("RequestCancelTimer", zap.String(tagTimerID, timerID)) | |||
} | |||
|
|||
func validateVersion(changeID string, version, minSupported, maxSupported Version) { |
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.
Can these methods return error message and panic at GetVersion() level? sometimes seeing too many panics in library code gives a feeling that panic is accepted pattern but we only do it in certain method calls, where error is not obvious choice.
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 is a helper method that has no much of logic inside. If we would return flag here and panic in GetVersion() level, then this method does not need to be exists.
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.
you can return error instead of flag. it is still good to have validation as a separate method.
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.
Use error when invalid version is expected in legit case, and call site can handle that error accordingly. In this case, invalid version is not expected, and it is not recoverable. So I think panic is appropriate here.
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.
instead of panic'ing here, panic inside GetVersion() if validateVersion() returns error. so it is very clear that method panics.
internal_event_handlers.go
Outdated
version = DefaultVersion | ||
} | ||
validateVersion(changeID, version, minSupported, maxSupported) | ||
wc.logger.Debug("GetVersion return version from a marker", |
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.
Can you hide this logger under the verbose check?
internal_event_handlers.go
Outdated
version = maxSupported | ||
wc.decisionsHelper.recordVersionMarker(changeID, version) | ||
|
||
wc.logger.Debug("GetVersion return", |
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.
same here? the more it looks this flag of checking to log looks hacky all over place.
internal_event_handlers.go
Outdated
if attributes.GetMarkerName() != sideEffectMarkerName { | ||
switch attributes.GetMarkerName() { | ||
case sideEffectMarkerName: | ||
dec := gob.NewDecoder(bytes.NewBuffer(attributes.GetDetails())) |
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.
Why are you not using encoding interface on hostEnv to decode, so we can switch easily with a different encoder.
internal_worker_base.go
Outdated
@@ -53,6 +53,7 @@ type ( | |||
asyncActivityClient | |||
workflowTimerClient | |||
SideEffect(f func() ([]byte, error), callback resultHandler) | |||
GetVersion(changeID string, maxSupported, minSupported Version) Version |
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 order of variables is inversed. minSupported, maxSupported. Can you add unit test for this layer as well?
internal_workflow.go
Outdated
@@ -327,6 +328,7 @@ func (d *syncWorkflowDefinition) Execute(env workflowEnvironment, input []byte) | |||
d.rootCtx = WithValue(background, workflowEnvironmentContextKey, env) | |||
var resultPtr *workflowResult | |||
d.rootCtx = WithValue(d.rootCtx, workflowResultContextKey, &resultPtr) | |||
d.rootCtx = WithValue(d.rootCtx, changeVersionsContextKey, make(map[string]Version)) |
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.
What is the value if having this look up in this layer when you have the lookup already in task handler GetVersion()?
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 layer server as a cache so we always return same version for same changeID, only if the changeID is known ID. The lookup at workflowEnvironment layer serve lookup from marker result. If a changeID is not present at workflowEnvironment layer, we would return DefaultVersion, but if a changeID is not present at here, we won't return DefaultVersion.
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 2 layer lookup can be combined, just updated.
1 similar comment
@@ -335,6 +335,40 @@ func (wc *workflowEnvironmentImpl) RequestCancelTimer(timerID string) { | |||
wc.logger.Debug("RequestCancelTimer", zap.String(tagTimerID, timerID)) | |||
} | |||
|
|||
func validateVersion(changeID string, version, minSupported, maxSupported Version) { |
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.
you can return error instead of flag. it is still good to have validation as a separate method.
workflowFn := func(ctx Context) error { | ||
ctx = WithActivityOptions(ctx, s.activityOptions) | ||
var f Future | ||
v := GetVersion(ctx, "test_change_id", DefaultVersion, 2) |
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.
Looking at this we probably want to change DefaultVersion value to 1.
This is based on #170, the only change is changing the map that attached to rootCtx from type map[string]*changeVersion to map[string]Version, as a result, also change the cadence.GetVersion() code a little bit.