Skip to content

NexusSerializationContext for data/failure converters - #1828

Open
JoshuaFrenchwood wants to merge 3 commits into
mainfrom
adding-nexus-serialization-context
Open

NexusSerializationContext for data/failure converters#1828
JoshuaFrenchwood wants to merge 3 commits into
mainfrom
adding-nexus-serialization-context

Conversation

@JoshuaFrenchwood

Copy link
Copy Markdown
Contributor

What was changed

Added NexusSerializationContext for nexus callers and sync handlers. This allows data and failure converters to use nexus endpoint, service and operation to be used for encoding and decoding.

Why?

This enables codecs to select serialization behavior or encryption keys by Nexus endpoint, service, or operation.

For example, workflows calling two Nexus endpoints can encrypt each endpoint’s payloads with a different key while ensuring that inputs, results, and failures are decoded with the converter selected for the corresponding operation.

Checklist

  1. Closes

  2. How was this tested:

Added unit/functional tests to verify that NexusSerializationContext works as expected.

  1. Any docs updates needed?

@JoshuaFrenchwood
JoshuaFrenchwood force-pushed the adding-nexus-serialization-context branch from f36df7a to 0774bf3 Compare September 9, 2026 20:09
@JoshuaFrenchwood
JoshuaFrenchwood marked this pull request as ready for review September 9, 2026 20:09
@JoshuaFrenchwood
JoshuaFrenchwood requested a review from a team as a code owner September 9, 2026 20:09
@JoshuaFrenchwood
JoshuaFrenchwood force-pushed the adding-nexus-serialization-context branch from 0774bf3 to 21ee938 Compare September 9, 2026 20:16
Comment thread temporalio/worker/_workflow_instance.py Outdated
if self._input.summary:
command.user_metadata.summary.CopyFrom(
self._payload_converter.to_payload(self._input.summary)
self._summary_payload_converter.to_payload(self._input.summary)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be the only case where we ensure a contextless serialization for summary, and I'm not sure that would remain true for codec application. Why do this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this, and just used the context serialization for summary

self._workflow_context_failure_converter,
)
summary_payload_converter = payload_converter
failure_converter = self._context_free_failure_converter

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a todo here. @VegetarianOrc already needs to extend this for worker callbacks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a TODO for this

Comment thread temporalio/worker/_nexus.py Outdated
service_handler is None
or operation not in service_handler.service.operation_definitions
):
return self._data_converter

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this really be a silent fallback to not having context? Why did we even need to find the service handler?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the fallback from here, and just returned the nexus serialization context directly

Comment thread temporalio/client/_interceptor.py Outdated
rpc_metadata: Mapping[str, str | bytes]
rpc_timeout: timedelta | None
result_type: type[Any] | None
_nexus_serialization_context: NexusSerializationContext | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like this should be on the intercepted object.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was able to remove this because I moved decoding to the nexus operation handle

),
)

async def get_nexus_operation_result(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may need some thought, it appears to work differently from any other interceptor or handle in the SDK, which is why you needed to pass the context through the interceptor. None of the others actually perform decoding, and this is the only result getter which allows for interception.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I moved the decoding logic into the nexus operation handle.

@JoshuaFrenchwood
JoshuaFrenchwood force-pushed the adding-nexus-serialization-context branch from 070740b to c91cfa3 Compare September 10, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants