-
Notifications
You must be signed in to change notification settings - Fork 61
fix: mark system Nexus envelope payloads #799
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
Changes from all commits
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 |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using Google.Protobuf; | ||
|
|
@@ -125,20 +126,9 @@ await childCodec2.DecodeFailureAsync( | |
| } | ||
| if (job.ResolveNexusOperation.Result.Completed != null) | ||
| { | ||
| var operationInfo = context.Instance?.GetPendingNexusOperationInfo( | ||
| job.ResolveNexusOperation.Seq); | ||
| if (operationInfo == null || | ||
| !await SystemNexusPayloadVisitor.TryVisitOutputAsync( | ||
| operationInfo.Endpoint, | ||
| job.ResolveNexusOperation.Result.Completed, | ||
| payload => DecodeAsync(nexusCodec, payload), | ||
| payloads => DecodeAsync(nexusCodec, payloads)). | ||
| ConfigureAwait(false)) | ||
| { | ||
| await DecodeAsync( | ||
| nexusCodec, job.ResolveNexusOperation.Result.Completed). | ||
| ConfigureAwait(false); | ||
| } | ||
| await DecodeAsync( | ||
| nexusCodec, job.ResolveNexusOperation.Result.Completed). | ||
|
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. This payload possibly does not have the system payload marker on it even if it is a system payload. Which means that it'll go through the normal user codec decode path and then fail deserialization causing the workflow to continuously fail the task and timeout the ExecuteWorkflowAsync_SignalWithStartFromWorkflow_Succeeds test. Might need to check for the marker or see if it's from the system nexus endpoint; or maybe somehow stamp the payload with the marker if it comes from the system nexus endpoint before we attempt the decode here.
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. In what scenario would it be a system payload without the system payload marker? That should be tautologically equivalent as far as I know. (At least once server is updated sufficiently) Are you talking backwards compat or something else?
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. Back compat. Today, system payloads are identified by the endpoint, but this change completely drops that (I think). So in-flight workflows that do not have the new marker now going through the path of decoding the envelop. But if you don't care about those, then I think this is fine. But I see that
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, this was in draft for a reason. All you say is true, but it's also not enabled at all yet, so we're good to do the breaking change. Nice catch though. |
||
| ConfigureAwait(false); | ||
| } | ||
| else if (job.ResolveNexusOperation.Result.Failed != null) | ||
| { | ||
|
|
@@ -347,16 +337,7 @@ await EncodeAsync( | |
| codec = context.CodecNoContext; | ||
| if (cmd.ScheduleNexusOperation.Input != null && codec != null) | ||
| { | ||
| if (!await SystemNexusPayloadVisitor.TryVisitInputAsync( | ||
| cmd.ScheduleNexusOperation.Endpoint, | ||
| cmd.ScheduleNexusOperation.Input, | ||
| payload => EncodeAsync(codec, payload), | ||
| payloads => EncodeAsync(codec, payloads)). | ||
| ConfigureAwait(false)) | ||
| { | ||
| await EncodeAsync( | ||
| codec, cmd.ScheduleNexusOperation.Input).ConfigureAwait(false); | ||
| } | ||
| await EncodeAsync(codec, cmd.ScheduleNexusOperation.Input).ConfigureAwait(false); | ||
| } | ||
| break; | ||
| case WorkflowCommand.VariantOneofCase.StartChildWorkflowExecution: | ||
|
|
@@ -429,15 +410,43 @@ private static async Task EncodeAsync( | |
| { | ||
| return; | ||
| } | ||
| // We have to convert to list here just in case they are based on the underlying list | ||
| // and we clear it out (which can happen with Linq selectors) | ||
| var newPayloads = (await codec.EncodeAsync(payloads).ConfigureAwait(false)).ToList(); | ||
| var newPayloads = new List<Payload>(); | ||
| var codecPayloads = new List<Payload>(); | ||
| foreach (var payload in payloads) | ||
| { | ||
| if (!await SystemNexusPayloadVisitor.TryVisitAsync( | ||
| payload, | ||
| payload => EncodeAsync(codec, payload), | ||
| nestedPayloads => EncodeAsync(codec, nestedPayloads)).ConfigureAwait(false)) | ||
| { | ||
| codecPayloads.Add(payload); | ||
| continue; | ||
| } | ||
|
|
||
| if (codecPayloads.Count > 0) | ||
| { | ||
| newPayloads.AddRange(await codec.EncodeAsync(codecPayloads).ConfigureAwait(false)); | ||
| codecPayloads.Clear(); | ||
| } | ||
| newPayloads.Add(payload); | ||
| } | ||
| if (codecPayloads.Count > 0) | ||
| { | ||
| newPayloads.AddRange(await codec.EncodeAsync(codecPayloads).ConfigureAwait(false)); | ||
| } | ||
| payloads.Clear(); | ||
| payloads.AddRange(newPayloads); | ||
| } | ||
|
|
||
| private static async Task EncodeAsync(IPayloadCodec codec, Payload payload) | ||
| { | ||
| if (await SystemNexusPayloadVisitor.TryVisitAsync( | ||
| payload, | ||
| nestedPayload => EncodeAsync(codec, nestedPayload), | ||
| nestedPayloads => EncodeAsync(codec, nestedPayloads)).ConfigureAwait(false)) | ||
| { | ||
| return; | ||
| } | ||
| // We are gonna require a single result here. It is important that we do Single() call | ||
| // before clearing out payload to merge with since underlying enumerable may be lazy. | ||
| // If the returned payload is literally the same object as the one sent to the codec, | ||
|
|
@@ -538,15 +547,43 @@ private static async Task DecodeAsync(IPayloadCodec codec, RepeatedField<Payload | |
| { | ||
| return; | ||
| } | ||
| // We have to convert to list here just in case they are based on the underlying list | ||
| // and we clear it out (which can happen with Linq selectors) | ||
| var newPayloads = (await codec.DecodeAsync(payloads).ConfigureAwait(false)).ToList(); | ||
| var newPayloads = new List<Payload>(); | ||
| var codecPayloads = new List<Payload>(); | ||
| foreach (var payload in payloads) | ||
| { | ||
| if (!await SystemNexusPayloadVisitor.TryVisitAsync( | ||
| payload, | ||
| payload => DecodeAsync(codec, payload), | ||
| nestedPayloads => DecodeAsync(codec, nestedPayloads)).ConfigureAwait(false)) | ||
| { | ||
| codecPayloads.Add(payload); | ||
| continue; | ||
| } | ||
|
|
||
| if (codecPayloads.Count > 0) | ||
| { | ||
| newPayloads.AddRange(await codec.DecodeAsync(codecPayloads).ConfigureAwait(false)); | ||
| codecPayloads.Clear(); | ||
| } | ||
| newPayloads.Add(payload); | ||
| } | ||
| if (codecPayloads.Count > 0) | ||
| { | ||
| newPayloads.AddRange(await codec.DecodeAsync(codecPayloads).ConfigureAwait(false)); | ||
| } | ||
| payloads.Clear(); | ||
| payloads.AddRange(newPayloads); | ||
| } | ||
|
|
||
| private static async Task DecodeAsync(IPayloadCodec codec, Payload payload) | ||
| { | ||
| if (await SystemNexusPayloadVisitor.TryVisitAsync( | ||
| payload, | ||
| nestedPayload => DecodeAsync(codec, nestedPayload), | ||
| nestedPayloads => DecodeAsync(codec, nestedPayloads)).ConfigureAwait(false)) | ||
| { | ||
| return; | ||
| } | ||
| // We are gonna require a single result here. | ||
| // Similarly with encode, we leave the payload alone if it's exactly the same object as the original. | ||
| var decoded = await codec.DecodeAsync(new Payload[] { payload }).ConfigureAwait(false); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.