Repository navigation
Conversation
`@nexus.close` marks the method that ends a resource. Python closes it at a block's end with the block's error, TypeScript and .NET close it at the end of `await using`.
This was referenced Oct 28, 2026
Contributor
Author
|
Moved to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
This PR adds
@nexus.close, which marks the method that ends a resource, soasync withandawait usingclose it.__aenter__and__aexit__. At the block's end it asks the support package with_support.exit_close(self, exc)whether to close now, and with which failure, and then calls the close withfailure=. One class serves both targets, so the support package owns the policy. If the close fails, its error has the block's error as its__context__, as Python does for a context manager._support.ResourceCall, so bothawait client.create_stream(...)andasync with client.create_stream(...) as streamwork. This is the facade'sCreating. The function is a plain function now, and it builds the request when it is called.[Symbol.asyncDispose], and .NET gives itIAsyncDisposable. Both call the close with no failure, sinceawait usingdoesn't see the error. The TypeScript samples take theesnext.disposablelib for it.defer, and Java has no resources.nexgen refuses a second
@nexus.closeon a resource, a required parameter of the method, and afailurethat names no parameter of thetemporal.api.failure.v1.Failuretype.The sample support gives
exit_closeandResourceCall. Outside a Workflow, its policy closes on a clean exit and on anException, closes a cancel as Temporal'sCancelledErrorso the Store records canceled, and leaves the resource open for anotherBaseException, such asKeyboardInterrupt. In Workflow code it registers the handle with the run and doesn't close it, since the SDK may close it at the run's end or keep it open for a retry run.It sits on #333. The stack is #308, #310, #311, #297, #296, #303, #304, #309, #318, #319, #320, #321, #322, #323, #324, #325, #326, #327, #328, #329, #330, #331, #332, #333, then this PR.
Why?
The Stream API of the proposal creates a Stream in
async with, and the block's end closes it with the block's error. The facade has its ownCreatingand context manager for this today.How did you test it?
Python tests close a Stream at the end of a block that raises
ValueError, of a clean block, and of a canceled block, and check the failure of each close request. Others check that aKeyboardInterruptleaves the Stream open, that a failed close raises with the block's error as its context, and that Workflow code defers the close. A TypeScript test disposes a Stream and checks the close request, and a .NET compile check closes a Stream withawait using. A unit test checks the directive, and rejection fixtures cover each refusal.cargo validatepasses.