<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">It looks pretty inconsistent to have the API of the structured concurrency and of ExtentLocal have different design, especially when it seems like the 2 APIs have the same base assumptions.</p>
<p style="margin:0px 0px 1.2em!important">From my understanding those 2 features are meant for each other. I actually agree that allowing “weak” TwR for ExtentLocals is probably a bad idea, but I also believe the same for structured concurrency:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-java" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)">    <span class="hljs-function"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">void</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">foo</span><span class="hljs-params">()</span> </span>{
        var scope = <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">new</span> StructuredTaskScope.ShutdownOnFailure();
        var scope1 = <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">new</span> StructuredTaskScope.ShutdownOnFailure();

        scope.close();
        scope1.close();
    }
</code></pre>
<p style="margin:0px 0px 1.2em!important">This should fail on compile time.</p>
<p style="margin:0px 0px 1.2em!important">This is less important for the incubator, but for the preview I do think it is important to prevent weird bugs when people misusing the feature.<br>For example, I can see someone without understanding of structured concurrency writing the following:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-java" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)"><span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// abstraction of a calculation on "int[]" that can be partitioned and then aggregated into a single result</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// contains "int set/setCount()" for the count of partitions, a method "void calcPart(int[] lst, int partNumber)", "void aggregateParts()" and "int getResult()"</span>
<span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">public</span> <span class="hljs-class"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">interface</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(68,85,136);font-weight:bold">PartitiableAction</span> </span>{ ... } 
...
<span class="hljs-function"><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">public</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">static</span> <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">void</span> <span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold">calcAtOnce</span><span class="hljs-params">(Collection<PartitiableAction> actions, <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">int</span>[] input)</span> </span>{
   var scopes = <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">new</span> HashMap<PartitiableAction, StructuredTaskScope.ShutdownOnFailure>();
   <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// start a scope for each action</span>
   <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">for</span> (var action : actions) {
       var scope = <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">new</span> StructuredTaskScope.ShutdownOnFailure();
        scopes.put(action, scope);
         <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// new thread for each part of the calculation</span>
        <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">for</span> (var j = <span class="hljs-number" style="color:rgb(0,128,128)">0</span>; j < action.getCount(); j++)  scope.fork(() =>   action.calcPart(input, j));
   }

   <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic">// !! Undefined behavior !!</span>
   <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold">for</span> (var action : actions) {
         var scope = scopes.get(action);
         scope.join();
         action.aggregateParts();
         scope.close();
    }

}
</code></pre>
<p style="margin:0px 0px 1.2em!important">Some implementations of <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">Collection</code> that will always fail, some will always succeed, and some implementations (like <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">HashSet</code>) may be non-deterministic.<br>For the uninformed this method makes sense, for each <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">PartitiableAction</code> I create some kind of a new “<code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">Executor</code>“ that everyone is talking about, if one of the parts fails, the whole calculation of this specific <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">PartitiableAction</code> will stop running, and I am waiting for everything to end.</p>
<hr>
<p style="margin:0px 0px 1.2em!important">I can write a PoC compiler plugin such that classes with <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">@StrongTwR</code> annotation can only be assigned inside TwR (unless they are also the return value) (I will probably do it tomorrow and send a link to it in a follow up mail if people are interested)</p>
<div title="MDH:SXQgbG9va3MgcHJldHR5IGluY29uc2lzdGVudCB0byBoYXZlIHRoZSBBUEkgb2YgdGhlIHN0cnVj
dHVyZWQgY29uY3VycmVuY3kgYW5kIG9mIEV4dGVudExvY2FsIGhhdmUgZGlmZmVyZW50IGRlc2ln
biwgZXNwZWNpYWxseSB3aGVuIGl0IHNlZW1zIGxpa2UgdGhlIDIgQVBJcyBoYXZlIHRoZSBzYW1l
IGJhc2UgYXNzdW1wdGlvbnMuPGRpdj48YnI+PC9kaXY+PGRpdj5Gcm9tIG15Jm5ic3A7dW5kZXJz
dGFuZGluZyB0aG9zZSAyIGZlYXR1cmVzIGFyZSBtZWFudCBmb3IgZWFjaCBvdGhlci4gSSBhY3R1
YWxseSBhZ3JlZSB0aGF0IGFsbG93aW5nICJ3ZWFrIiBUd1IgZm9yIEV4dGVudExvY2FscyBpcyBw
cm9iYWJseSBhIGJhZCBpZGVhLCBidXQgSSBhbHNvIGJlbGlldmUgdGhlIHNhbWUgZm9yIHN0cnVj
dHVyZWQgY29uY3VycmVuY3k6PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5gYGBqYXZhPC9kaXY+
PGRpdj4mbmJzcDsgJm5ic3A7IHZvaWQgZm9vKCkgezxicj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgdmFyIHNjb3BlID0gbmV3IFN0cnVjdHVyZWRUYXNrU2NvcGUuU2h1dGRvd25PbkZhaWx1
cmUoKTs8YnI+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHZhciBzY29wZTEgPSBuZXcgU3Ry
dWN0dXJlZFRhc2tTY29wZS5TaHV0ZG93bk9uRmFpbHVyZSgpOzxicj48YnI+Jm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7IHNjb3BlLmNsb3NlKCk7PGJyPiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyBzY29wZTEuY2xvc2UoKTs8YnI+Jm5ic3A7ICZuYnNwOyB9PGJyPjwvZGl2PjxkaXY+YGBg
PC9kaXY+PGRpdj5UaGlzIHNob3VsZCBmYWlsIG9uIGNvbXBpbGUgdGltZS48L2Rpdj48ZGl2Pjxi
cj48L2Rpdj48ZGl2PlRoaXMgaXMgbGVzcyBpbXBvcnRhbnQgZm9yIHRoZSBpbmN1YmF0b3IsIGJ1
dCBmb3IgdGhlIHByZXZpZXcmbmJzcDtJIGRvIHRoaW5rIGl0IGlzIGltcG9ydGFudCB0byBwcmV2
ZW50IHdlaXJkIGJ1Z3Mgd2hlbiBwZW9wbGUgbWlzdXNpbmcgdGhlIGZlYXR1cmUuPC9kaXY+PGRp
dj5Gb3IgZXhhbXBsZSwgSSBjYW4gc2VlIHNvbWVvbmUgd2l0aG91dCB1bmRlcnN0YW5kaW5nIG9m
IHN0cnVjdHVyZWQgY29uY3VycmVuY3kgd3JpdGluZyB0aGUgZm9sbG93aW5nOjwvZGl2PjxkaXY+
YGBgamF2YTwvZGl2PjxkaXY+Ly8gYWJzdHJhY3Rpb24gb2YgYSBjYWxjdWxhdGlvbiBvbiAiaW50
W10iIHRoYXQgY2FuIGJlIHBhcnRpdGlvbmVkIGFuZCB0aGVuIGFnZ3JlZ2F0ZWQgaW50byBhIHNp
bmdsZSByZXN1bHQ8L2Rpdj48ZGl2Pi8vIGNvbnRhaW5zICJpbnQgc2V0L3NldENvdW50KCkiIGZv
ciB0aGUgY291bnQgb2YgcGFydGl0aW9ucywgYSBtZXRob2QgInZvaWQgY2FsY1BhcnQoaW50W10g
bHN0LCBpbnQgcGFydE51bWJlcikiLCAidm9pZCBhZ2dyZWdhdGVQYXJ0cygpIiBhbmQgImludCBn
ZXRSZXN1bHQoKSI8YnI+PC9kaXY+PGRpdj5wdWJsaWMgaW50ZXJmYWNlIFBhcnRpdGlhYmxlQWN0
aW9uIHsgLi4uIH0mbmJzcDs8L2Rpdj48ZGl2Pi4uLjwvZGl2PjxkaXY+cHVibGljIHN0YXRpYyB2
b2lkIGNhbGNBdE9uY2UoQ29sbGVjdGlvbiZsdDtQYXJ0aXRpYWJsZUFjdGlvbiZndDsgYWN0aW9u
cywgaW50W10gaW5wdXQpIHs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDt2YXIgc2NvcGVzID0gbmV3
IEhhc2hNYXAmbHQ7UGFydGl0aWFibGVBY3Rpb24sIFN0cnVjdHVyZWRUYXNrU2NvcGUuU2h1dGRv
d25PbkZhaWx1cmUmZ3Q7KCk7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7Ly8gc3RhcnQgYSBzY29w
ZSBmb3IgZWFjaCBhY3Rpb248L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDtmb3IgKHZhciBhY3Rpb24g
OiBhY3Rpb25zKSB7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDt2YXIgc2Nv
cGUgPSBuZXcgU3RydWN0dXJlZFRhc2tTY29wZS5TaHV0ZG93bk9uRmFpbHVyZSgpOzwvZGl2Pjxk
aXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHNjb3Blcy5wdXQoYWN0aW9uLCBzY29wZSk7
PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7Ly8gbmV3IHRocmVh
ZCBmb3IgZWFjaCBwYXJ0IG9mIHRoZSBjYWxjdWxhdGlvbjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7IGZvciAodmFyIGogPSAwOyBqICZsdDsgYWN0aW9uLmdldENvdW50KCk7
IGorKykmbmJzcDsgc2NvcGUuZm9yaygoKSA9Jmd0OyZuYnNwOwoKYWN0aW9uLmNhbGNQYXJ0KGlu
cHV0LCBqKSk7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7fTwvZGl2PjxkaXY+PGJyPjwvZGl2Pjxk
aXY+Jm5ic3A7ICZuYnNwOy8vICEhIFVuZGVmaW5lZCBiZWhhdmlvciAhITwvZGl2PjxkaXY+Jm5i
c3A7ICZuYnNwO2ZvciAodmFyIGFjdGlvbiA6IGFjdGlvbnMpIHs8L2Rpdj48ZGl2PiZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDt2YXIgc2NvcGUgPSBzY29wZXMuZ2V0KGFjdGlvbik7
PC9kaXY+wqAgwqAgwqAgwqAgwqBzY29wZS5qb2luKCk7PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7YWN0aW9uLmFnZ3JlZ2F0ZVBhcnRzKCk7PGJyPjxkaXY+Jm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwO3Njb3BlLmNsb3NlKCk7PGJyPiZuYnNwOyAmbmJzcDsm
bmJzcDt9PC9kaXY+PGRpdj48YnI+PGRpdj59PC9kaXY+PGRpdj5gYGA8L2Rpdj48ZGl2PlNvbWUg
aW1wbGVtZW50YXRpb25zIG9mIGBDb2xsZWN0aW9uYCB0aGF0IHdpbGwgYWx3YXlzIGZhaWwsIHNv
bWUgd2lsbCBhbHdheXMgc3VjY2VlZCwgYW5kIHNvbWUgaW1wbGVtZW50YXRpb25zIChsaWtlIGBI
YXNoU2V0YCkgbWF5IGJlIG5vbi1kZXRlcm1pbmlzdGljLjwvZGl2PjxkaXY+Rm9yIHRoZSB1bmlu
Zm9ybWVkJm5ic3A7dGhpcyBtZXRob2QgbWFrZXMgc2Vuc2UsIGZvciBlYWNoIGBQYXJ0aXRpYWJs
ZUFjdGlvbmAgSSBjcmVhdGUgc29tZSZuYnNwO2tpbmQgb2YgYSBuZXcgImBFeGVjdXRvcmAiIHRo
YXQgZXZlcnlvbmUgaXMgdGFsa2luZyBhYm91dCwgaWYgb25lIG9mIHRoZSBwYXJ0cyBmYWlscywg
dGhlIHdob2xlIGNhbGN1bGF0aW9uIG9mIHRoaXMgc3BlY2lmaWMgYFBhcnRpdGlhYmxlQWN0aW9u
YCB3aWxsIHN0b3AgcnVubmluZywgYW5kIEkgYW0gd2FpdGluZyBmb3IgZXZlcnl0aGluZyB0byBl
bmQuPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4tLS08L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2
PkkgY2FuIHdyaXRlIGEgUG9DIGNvbXBpbGVyIHBsdWdpbiBzdWNoIHRoYXQgY2xhc3NlcyB3aXRo
IGBAU3Ryb25nVHdSYCBhbm5vdGF0aW9uIGNhbiBvbmx5IGJlIGFzc2lnbmVkIGluc2lkZSBUd1Ig
KHVubGVzcyB0aGV5IGFyZSBhbHNvIHRoZSByZXR1cm4gdmFsdWUpPC9kaXY+PGRpdj48YnI+PC9k
aXY+PC9kaXY+PC9kaXY+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0"></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 4, 2022 at 11:51 AM Andrew Haley <<a href="mailto:aph-open@littlepinkcloud.com">aph-open@littlepinkcloud.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 7/29/22 21:37, Ron Pressler wrote:<br>
> Yes, we are thinking about a "strong” TwR, but we’re busy with so many things so it might take a while. Until then, we might introduce a weaker, or less trustworthy version of ExtentLocals that uses the existing TwR and wouldn’t be used for critical things, but we think that it’s best to start incubation with just the lambda API and then see what problems are most common/annoying and how we can best address them.<br>
<br>
One of the worst problems with using "weak" TWR for extent locals is that<br>
ensuring the invariants with respect to structured concurrency is hard.<br>
You end up with complex consistency checks that must be checked at runtime,<br>
and are hard to test.<br>
<br>
-- <br>
Andrew Haley  (he/him)<br>
Java Platform Lead Engineer<br>
Red Hat UK Ltd. <<a href="https://www.redhat.com" rel="noreferrer" target="_blank">https://www.redhat.com</a>><br>
<a href="https://keybase.io/andrewhaley" rel="noreferrer" target="_blank">https://keybase.io/andrewhaley</a><br>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr">Holo The Wise Wolf Of Yoitsu</div></div>