Klassenq/nexus per endpoint encryption - #872
JoshuaFrenchwood wants to merge 7 commits into
Conversation
Record the context on the workflow started event so mutable-state rebuilds and resets restore it through normal replay. Constraint: Reset rebuilds mutable state from history. Rejected: Copy context directly in workflow resetter | bypasses standard event reconstruction. Confidence: high Scope-risk: moderate Tested: make buf-lint api-linter go-grpc fix-path Not-tested: make grpc (blocked by pre-existing WorkerHeartbeat.environment breaking-change failure)
chrsmith
left a comment
There was a problem hiding this comment.
Apologies in advance if these are all non-concerns.
| message PropagatedNexusSerializationContext { | ||
| string endpoint = 1; | ||
| string service = 2; | ||
| // If more context is needed, this message can be extended with additional fields. |
There was a problem hiding this comment.
Nit: Isn't this kinda implied with any protobuf message contract? Seems like we can just remove this comment entirely.
There was a problem hiding this comment.
Agreed, I removed that comment
| map<string, Payload> fields = 1; | ||
| } | ||
|
|
||
| // PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity. |
There was a problem hiding this comment.
Nit: Would "execution" or "resource" be a better term here?
There was a problem hiding this comment.
Updated to use execution here
|
|
||
| // PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity. | ||
| // If multiple Nexus callers attempt to attach to the same entity the server will verify that | ||
| // each field matches, if any field does not match then the request will be rejected. |
There was a problem hiding this comment.
What about situations where multiple Nexus handlers are backed by the same Temporal execution?
e.g. a Nexus Service with two Nexus handlers, each of which spawns a standalone Activity, with the ID Conflict policy USE_EXISTING. The first call would create the SAA. The second Nexus handler would need to provide a different PropagatedNexusSerializationContext to that SAA, right? (And attach another completion callback, so that when the SAA completes, both Nexus handlers would effective return to their callers.)
Am I missing something about how this is supposed to work?
There was a problem hiding this comment.
In the current design the second request will be rejected. So when using USE_EXISTING conflict policy, you would have to have the same PropagatedNexusSerializationContext.
There was a problem hiding this comment.
So Nexus handlers with different endpoint, service or operation cannot share the same backing execution (Workflow or SAA)
There was a problem hiding this comment.
Thanks for the clarification. Let ping you offline to chat about this more, since I don't know how much of a problem that would be in-practice. (And just want to make sure we've thought it through and are OK with the limitation.)
e.g. I can imagine scenarios where a user would want to expose the same Nexus service from different endpoints, since that would allow you to manually set up things like having different rate limits or worker pools. At least as a workaround until we can expand upon the configuration knobs available in TCloud.
Even then, it might be acceptable... since you would at least control the code at the callsite wherever you specify the USE_EXISTING conflict policy. (And could therefore opt to not do that if doing so would lead to problems.)
| temporal.api.common.v1.OnConflictOptions on_conflict_options = 21; | ||
| // Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts. | ||
| google.protobuf.Duration start_delay = 22; | ||
| // Serialization context propagated from the Nexus caller that started this activity. |
There was a problem hiding this comment.
We need to add this PropagateNexusSerializationContext to every Start- and Describe- operation, for each kind of execution. Right?
If so, it looks like we missed standalone Nexus operations. e.g. NexusOperationExecutionInfo and StartNexusOperationExecutionRequest.
https://github.com/temporalio/api/blob/main/temporal/api/nexus/v1/message.proto#L246
There was a problem hiding this comment.
For those they already have the operation/service/endpoint, so we dont need to add this there.
| // PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. | ||
| // Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their | ||
| // endpoint, service, and operation match. A request with a different context is rejected. | ||
| message PropagatedNexusSerializationContext { |
There was a problem hiding this comment.
We can put this in the nexus package if there are no circular import concerns.
There was a problem hiding this comment.
Moved to nexus package
| // according to the weights. | ||
| temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 19; | ||
| // Serialization context propagated from the Nexus caller that started this workflow. | ||
| temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 20; |
There was a problem hiding this comment.
Do we need this here given that we have it on the WorkflowExecutionStarted event attributes?
There was a problem hiding this comment.
The History field in PollWorkflowTaskQueueResponse has WorkflowExecutionStarted attributes, but the comment above it says that partial histories may be sent to workers that are using sticky queue. So I included here directly
There was a problem hiding this comment.
The worker can store this information per workflow run though. I don't see a good enough reason to send it with every task.
|
Please do not merge this until you have a working end to end prototype using the server and a single SDK. |
| // PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. | ||
| // Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their | ||
| // endpoint, service, and operation match. A request with a different context is rejected. | ||
| message PropagatedNexusSerializationContext { |
There was a problem hiding this comment.
Suggesting that we don't stutter here, we're already in the nexus package.
| message PropagatedNexusSerializationContext { | |
| message PropagatedSerializationContext { |
What changed?
Added
PropagatedNexusSerializationContextwith endpoint, service, and operation fields. Added it to workflow, activity, and update APIs, including start requests, task poll responses, workflow details, and the workflow-started history event.Why?
Nexus callers need their serialization context carried to the entities they start. Recording it in workflow history also lets replay and reset restore that context
Breaking changes
Server PR