<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">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.<div class=""><br class=""></div><div class="">Most tracing libraries (ignore byte code instrumentation) work like this:</div><div class=""><br class=""></div><div class="">void topLevelRequestHandler(Request r,Response) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>getTracingContext().setRequestId(r.getId());</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>… eventually call myFunction() which is traced ...</div><div class="">}</div><div class=""><br class=""></div><div class="">void myFunction(…) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>getTracingContext().startMethod(“myFunction”,…);</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>… do work …</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>getTracingContext().endMethod(“myFunction”,….);</div><div class="">}</div><div class=""><br class=""></div><div class="">or</div><div class=""><br class=""></div><div class="">void myFunction() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>// using AutoClosable</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>try(getTracingContext().start(“…”) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>... do work ...</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">If I were to rewrite the above using scoped variables, I THINK it would look something like:</div><div class=""><br class=""></div><div class=""><div class="">private static final ScopedValue<TracingContext> X = ScopedValue.newInstance();</div><div class=""><br class=""></div><div class=""><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">void topLevelRequestHandler(Request r,Response) {</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>ScopedValue.where(X,new TracingContext(r.getRequestId())).run(() -> myFunction(…);</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">}</div></div><div class=""><br class=""></div><div class="">void myFunction() {</div><div class=""> X.in(“myFunction”,...);</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>… do work ...</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> X.out(“myFunction”,...);</div><div class="">}</div><div class=""><br class=""></div><div class="">X.in() could return an AutoClosable, so you would have:</div><div class=""><br class=""></div><div class=""><div class="">void myFunction() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>try(X.in(“myFunction”,...)) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>… do work …</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div class="">}</div></div><div class=""><br class=""></div><div class="">which would “work”, but something more complicated, where X would be rebound as you went deeper in the call stack might be better.</div><div class=""><br class=""></div><div class="">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(…)</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div></div><div class=""><div><blockquote type="cite" class=""><div class="">On Jun 10, 2024, at 3:44 PM, Marcin Grzejszczak <<a href="mailto:marcin.grzejszczak@gmail.com" class="">marcin.grzejszczak@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="auto" class="">I'm sorry but I think I'm just very bad at explaining. </div><div dir="auto" class=""><br class=""></div><div dir="auto" class="">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. </div><div dir="auto" class=""><br class=""></div><div dir="auto" class="">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.</div><div dir="auto" class=""><br clear="all" class=""><div dir="auto" class=""><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div class="">Pozdrawiam / Best regards,</div><div class="">Marcin Grzejszczak</div><div class=""><br class=""><div class=""><a href="https://marcin.grzejszczak.pl/" target="_blank" class="">https://marcin.grzejszczak.pl</a></div><div class=""><a href="https://toomuchcoding.com/" target="_blank" class="">https://toomuchcoding.com</a></div></div></div></div></div></div></div></div><div class=""><br class=""></div><div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 10 Jun 2024 at 19:34, Robert Engels <<a href="mailto:robaho@icloud.com" class="">robaho@icloud.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">But x == y does not require immutability, .e.g:<br class="">
<br class="">
final ScopedValue aScopedValue = …<br class="">
<br class="">
Recorder r = aScopedValue.get();<br class="">
<br class="">
r.recordSomeValue();<br class="">
<br class="">
final Recorder = aScopedValue.get();<br class="">
<br class="">
r.close() -> e.g. writes values to server…<br class="">
<br class="">
so the scoped value is not immutable, only the reference is constant.<br class="">
<br class="">
This doesn’t match the JEP or I am misunderstanding it.<br class="">
<br class="">
> final ScopedValue aScopedValue = ...;<br class="">
> final var x = aScopedValue.get();<br class="">
> // Any Java code at all...<br class="">
> final var y = aScopedValue.get();<br class="">
<br class="">
<br class="">
<br class="">
> On Jun 10, 2024, at 12:29 PM, Andrew Haley <<a href="mailto:aph-open@littlepinkcloud.com" target="_blank" class="">aph-open@littlepinkcloud.com</a>> wrote:<br class="">
> <br class="">
> On 6/10/24 17:25, Robert Engels wrote:<br class="">
>> I think the question is more - what are the threads doing with this<br class="">
>> object between the open and close. This is what controls whether or not<br class="">
>> the object can be immutable - which from my reading is the general<br class="">
>> design/limitation of a scoped variable.<br class="">
> <br class="">
> Exactly. So something (what?) returns a Scope object. But that can't change<br class="">
> the current scoped value context.<br class="">
> <br class="">
> Here's a fundamental property of a scoped value:<br class="">
> <br class="">
> The result of aScopedValue.get() does not ever change within the execution<br class="">
> context of a method. Sure, its value might get overridden in the context of a<br class="">
> callee, but when that callee returns the scoped value has its original<br class="">
> value.<br class="">
> <br class="">
> So, in this code<br class="">
> <br class="">
> final ScopedValue aScopedValue = ...;<br class="">
> final var x = aScopedValue.get();<br class="">
> // Any Java code at all...<br class="">
> final var y = aScopedValue.get();<br class="">
> <br class="">
> assert(x == y); // Always succeeds<br class="">
> <br class="">
> That is to say, you can read a scoped value, put it in a local, and use<br class="">
> that local, and it is a hard guarantee that will have exactly the same<br class="">
> effect as repeatedly calling aScopedValue.get() .<br class="">
> <br class="">
> -- <br class="">
> Andrew Haley (he/him)<br class="">
> Java Platform Lead Engineer<br class="">
> Red Hat UK Ltd. <<a href="https://www.redhat.com/" rel="noreferrer" target="_blank" class="">https://www.redhat.com</a>><br class="">
> <a href="https://keybase.io/andrewhaley" rel="noreferrer" target="_blank" class="">https://keybase.io/andrewhaley</a><br class="">
> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671<br class="">
> <br class="">
<br class="">
</blockquote></div></div>
</div></blockquote></div><br class=""></div></body></html>