ScopedValue.runWhere not returning scope

Robert Engels robaho at icloud.com
Mon Jun 10 21:43:19 UTC 2024


Minor correction, the ScopedValue code should be similar to

X.get().in(“myFunction”,…)



> On Jun 10, 2024, at 4:11 PM, Robert Engels <robaho at icloud.com> wrote:
> 
> i think the problem may be your reference to “using a lambda”. I am not sure what that has to do with tracing libraries or thread locals.
> 
> Most tracing libraries (ignore byte code instrumentation) work like this:
> 
> void topLevelRequestHandler(Request r,Response) {
> 	getTracingContext().setRequestId(r.getId());
> 
> 	… eventually call myFunction() which is traced ...
> }
> 
> void myFunction(…) {
> 	getTracingContext().startMethod(“myFunction”,…);
> 	… do work …
> 	getTracingContext().endMethod(“myFunction”,….);
> }
> 
> or
> 
> void myFunction() {
> 	// using AutoClosable
> 	try(getTracingContext().start(“…”) {
> 		... do work ...
> 	}
> }
> 
> getTracingContext() will usually use a TL to get the context associated with the current execution. This eliminates the need to pass a context instance as a parameter of every method. It probably use an InheritableTL to handle the case of spawning additional threads to do some of the request handling.
> 
> You can rewrite the above without using TL by creating the TracingContext instance in the top level, and passing it as a parameter to every function below. This is how Go handles this.
> 
> A scoped variable is still backed by a map of VT -> instance, but it can be a bit more efficient when passing to sub tasks or methods - I believe it can avoid performing the map lookup multiple times.
> 
> If I were to rewrite the above using scoped variables, I THINK it would look something like:
> 
> private static final ScopedValue<TracingContext> X = ScopedValue.newInstance();
> 
> void topLevelRequestHandler(Request r,Response) {
> 	ScopedValue.where(X,new TracingContext(r.getRequestId())).run(() -> myFunction(…);
> }
> 
> void myFunction() {
>     X.in(“myFunction”,...);
> 	… do work ...
>     X.out(“myFunction”,...);
> }
> 
> X.in() could return an AutoClosable, so you would have:
> 
> void myFunction() {
> 	try(X.in(“myFunction”,...)) {
> 		… do work …
> 	}
> }
> 
> which would “work”, but something more complicated, where X would be rebound as you went deeper in the call stack might be better.
> 
> BUT — ScopedValue instances are supposed to be immutable, and in() and out() would be mutating the TracingContext() (most likely, it could defer to some other linked object or service call). Maybe the JEP meant to state the reference is immutable - i.e. you cannot change it directly, only using ScopedVariable.where(…)
> 
> and whether that is OK I don’t know. I am guessing for usability it would not be a private static instance, but rather a public static global - which is a problem in itself.
> 
>> On Jun 10, 2024, at 3:44 PM, Marcin Grzejszczak <marcin.grzejszczak at gmail.com <mailto:marcin.grzejszczak at gmail.com>> wrote:
>> 
>> I'm sorry but I think I'm just very bad at explaining. 
>> 
>> What I'm just trying to say is that the only thing that I think would be beneficial in terms of the api changes is that instead of passing the lambda that is doing all the safe keeping for the user (because it limits what can be done because of the usage of lambda) one would be able to literally do the same but not through the lambda but through manual start and stop. The rest of the assumptions would remain the same regardless of whether one using a lambda or not. 
>> 
>> I look at my request in a way as if you could do try with resources or manually call close in the finally block. In our scenario either the user passws the lambda or manually create the scope, runs the code (lambda) and closes the scope. Scope opening and closing would do exactly the same what it's being done under the hood when you call the lambda version.
>> 
>> Pozdrawiam / Best regards,
>> Marcin Grzejszczak
>> 
>> https://marcin.grzejszczak.pl <https://marcin.grzejszczak.pl/>
>> https://toomuchcoding.com <https://toomuchcoding.com/>
>> 
>> 
>> On Mon, 10 Jun 2024 at 19:34, Robert Engels <robaho at icloud.com <mailto:robaho at icloud.com>> wrote:
>> But x == y does not require immutability, .e.g:
>> 
>> final ScopedValue aScopedValue = …
>> 
>> Recorder r = aScopedValue.get();
>> 
>> r.recordSomeValue();
>> 
>> final Recorder = aScopedValue.get();
>> 
>> r.close() -> e.g. writes values to server…
>> 
>> so the scoped value is not immutable, only the reference is constant.
>> 
>> This doesn’t match the JEP or I am misunderstanding it.
>> 
>> >  final ScopedValue aScopedValue = ...;
>> >  final var x = aScopedValue.get();
>> >  // Any Java code at all...
>> >  final var y = aScopedValue.get();
>> 
>> 
>> 
>> > On Jun 10, 2024, at 12:29 PM, Andrew Haley <aph-open at littlepinkcloud.com <mailto:aph-open at littlepinkcloud.com>> wrote:
>> > 
>> > On 6/10/24 17:25, Robert Engels wrote:
>> >> I think the question is more - what are the threads doing with this
>> >> object between the open and close. This is what controls whether or not
>> >> the object can be immutable - which from my reading is the general
>> >> design/limitation of a scoped variable.
>> > 
>> > Exactly. So something (what?) returns a Scope object. But that can't change
>> > the current scoped value context.
>> > 
>> > Here's a fundamental property of a scoped value:
>> > 
>> >  The result of aScopedValue.get() does not ever change within the execution
>> >  context of a method. Sure, its value might get overridden in the context of a
>> >  callee, but when that callee returns the scoped value has its original
>> >  value.
>> > 
>> >  So, in this code
>> > 
>> >  final ScopedValue aScopedValue = ...;
>> >  final var x = aScopedValue.get();
>> >  // Any Java code at all...
>> >  final var y = aScopedValue.get();
>> > 
>> >  assert(x == y); // Always succeeds
>> > 
>> > That is to say, you can read a scoped value, put it in a local, and use
>> > that local, and it is a hard guarantee that will have exactly the same
>> > effect as repeatedly calling aScopedValue.get() .
>> > 
>> > -- 
>> > Andrew Haley  (he/him)
>> > Java Platform Lead Engineer
>> > Red Hat UK Ltd. <https://www.redhat.com <https://www.redhat.com/>>
>> > https://keybase.io/andrewhaley <https://keybase.io/andrewhaley>
>> > EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
>> > 
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20240610/8a480cd3/attachment-0001.htm>


More information about the loom-dev mailing list