Add resource-only scopes (resourceScope / ResourceScope)#480
Merged
Conversation
…pe end Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bridges keep the old JVM signatures via @TargetNAME, with distinct Scala-level names to avoid overload ambiguity at in-package call sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…guard Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The NoEnclosingConcurrencyScope given moves to the type's companion, so that it's found via the implicit scope without any imports - top-level givens are not brought in by wildcard imports, which made resourceScope unusable outside of the ox package (caught by the docs compilation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Parameterize the finalizer-error tests over both scope kinds, proving resourceScope's dedicated implementation shares runFinalizers semantics - Defer the delegator scaladocs to useInScope (canonical contract), removing the 4x-repeated concurrency-scope sentence - Align fork-completion wording with the dictionary (exception, not error); tighten the resourceScope scaladoc; drop restating comments - Document runFinalizers' single-shot contract; drop unneeded inline Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
Author
|
Release-note-worthy behavior change (surfaced in review): a finalizer which registers another finalizer on the same scope previously had the registration silently lost; it now fails the scope with an |
Per a test-minimality audit: reverse-order subsumes after-allocation; the finalizer-error scenarios and the register-only case pin shared runFinalizers logic, so a single scope kind suffices; the two leaked-capability tests merge into one (throw + message + eager release). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Adds resource scopes: scopes which allow attaching resources (
useInScope/releaseAfterScopestyle), but are not full concurrency scopes — no forking, no threads started while the body runs. Every concurrency scope can be used where a resource scope is expected (via subtyping:OxUnsupervised extends ResourceScope). This is ox's analogue ofscala.util.Using.Manager, and lets methods declare exactly the capability they need (using ResourceScope— attach cleanup, without claiming the ability to fork).Design highlights (adversarially critiqued before implementation):
resourceScopecannot be started where a concurrency scope is lexically visible (via aNotGiven-based given with a custom error message) — forks started within a lexically visible resource scope could outlive it. The recommended structure is extracting the scope to a capability-free method.IllegalStateExceptioninstead of being silently lost;useInScopereleases the just-acquired resource in that case, so cleanup is never lost. Applies uniformly to concurrency scopes.using ResourceScope; bridges with the oldusing OxUnsupervisedJVM signatures are kept via@targetName(with distinct Scala-level names, avoiding overload ambiguity) — MiMa passes with no new filters. Source compatibility is unaffected.ForkLocalsemantics pinned by tests: resources attach to the nearest enclosing scope; resource-scope finalizers see the fork-local values of the scope's own level.🤖 Generated with Claude Code