<div dir="ltr">





<p class="gmail-p1">Hello @loom-dev</p>
<p class="gmail-p1">When reading kotlin coroutine code:</p><p class="gmail-p1"><a href="https://github.com/Kotlin/kotlinx.coroutines/blob/8c27d51025d56a7b8de8eec2fb234b0094ce84f1/kotlinx-coroutines-core/common/src/Delay.kt#L9">https://github.com/Kotlin/kotlinx.coroutines/blob/8c27d51025d56a7b8de8eec2fb234b0094ce84f1/kotlinx-coroutines-core/common/src/Delay.kt#L9</a></p><p class="gmail-p1">







</p><p class="gmail-p1"><a href="https://github.com/Kotlin/kotlinx.coroutines/blob/8c27d51025d56a7b8de8eec2fb234b0094ce84f1/kotlinx-coroutines-core/common/src/Delay.kt#L149">https://github.com/Kotlin/kotlinx.coroutines/blob/8c27d51025d56a7b8de8eec2fb234b0094ce84f1/kotlinx-coroutines-core/common/src/Delay.kt#L149</a></p><p class="gmail-p1"><br></p>
<p class="gmail-p1">I came up with a new idea — what if we provide an additional <span class="gmail-s1">Delay</span> interface?</p><p class="gmail-p1">If the current scheduler implements this interface, we can use the scheduler’s own <span class="gmail-s1">delay</span> method.</p><p class="gmail-p2"><span class="gmail-s2">Otherwise, we fall back to `</span>DelayedTaskSchedulers.schedule`<span class="gmail-s2">.</span></p><p class="gmail-p1">Currently, Loom only optimizes <span class="gmail-s1">ForkJoinPool</span> for this case.</p><p class="gmail-p1">``` java</p><p class="gmail-p1">VirtualThreadScheduler scheduler(boolean revealBuiltin) {<br>    if (scheduler instanceof BuiltinDefaultScheduler builtin && !revealBuiltin) {<br>        return builtin.externalView();<br>    } else {<br>        return scheduler;<br>    }<br>}</p><p class="gmail-p1">```</p><p class="gmail-p3">






</p><p class="gmail-p1">But if I use Netty’s <span class="gmail-s1">EventLoop</span> as the scheduler, being able to implement delay based on the event loop would be fantastic.</p><p class="gmail-p1"><br></p><p class="gmail-p1">





</p><p class="gmail-p1">Best regards,</p><p class="gmail-p1">Mengyang Li</p></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">Alan Bateman <<a href="mailto:alan.bateman@oracle.com">alan.bateman@oracle.com</a>> 于2025年10月9日周四 01:44写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
  <div>
    <br>
    <br>
    <div>On 08/10/2025 15:57, Mengyang Li wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div dir="ltr">
          <p><br>
            ```<br>
          </p>
          <p>Console output:<br>
            ``` bash<br>
            WARNING: Using custom default scheduler, this is an
            experimental feature!<br>
            class java.lang.Thread<br>
            VirtualThread[#27,VirtualThreadA]/runnable RUNNABLE
            currentThread Thread[#3,main,5,main] current is virtual
            false<br>
            java.lang.RuntimeException<br>
                    at
io.github.dreamlike.CustomerVirtualThreadScheduler.execute(CustomerVirtualThreadScheduler.java:16)<br>
                    at
java.base/java.lang.VirtualThread.submitRunContinuation(VirtualThread.java:367)<br>
                    at
java.base/java.lang.VirtualThread.externalSubmitRunContinuationOrThrow(VirtualThread.java:456)<br>
                    at
            java.base/java.lang.VirtualThread.start(VirtualThread.java:734)<br>
                    at
            java.base/java.lang.VirtualThread.start(VirtualThread.java:745)<br>
                    at
java.base/java.lang.ThreadBuilders$VirtualThreadBuilder.start(ThreadBuilders.java:257)<br>
                    at io.github.dreamlike.VTMain.main(VTMain.java:14)<br>
            ```<br>
            <br>
          </p>
          <p>After checking the relevant code, it seems
            that execution goes through the <span><b>first
                branch</b></span> below.</p>
          <p>This behavior doesn’t appear to align with
            the semantics of a custom scheduler — the nested virtual
            thread is submitted directly to <span>ct.getPool()</span> instead
            of going through <span>CustomerVirtualThreadScheduler::execute</span>.<br>
          </p>
        </div>
      </div>
    </blockquote>
    Thanks for the mail. You are correct. There is confusion between the
    "custom default scheduler" and the "built-in default scheduler" when
    the former delegates to the latter. I'll sort it out.<br>
    <br>
    -Alan<br>
  </div>

</blockquote></div>