<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://asyncband.apache.org/blog/</id>
    <title>Apache Asyncband (Incubating) Blog</title>
    <updated>2026-10-14T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://asyncband.apache.org/blog/"/>
    <subtitle>Apache Asyncband (Incubating) Blog</subtitle>
    <icon>https://asyncband.apache.org/favicon.svg</icon>
    <entry>
        <title type="html"><![CDATA[Counting, Signaling, and Cancelling: Choosing the Right Asyncband Primitive]]></title>
        <id>https://asyncband.apache.org/blog/2026/10/14/choosing-the-right-primitive/</id>
        <link href="https://asyncband.apache.org/blog/2026/10/14/choosing-the-right-primitive/"/>
        <updated>2026-10-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A field guide to picking between Semaphore, ManualResetEvent, and AutoResetEvent, and the sharp edges worth knowing before you rely on them.]]></summary>
        <content type="html"><![CDATA[<p><em>This post is written against asyncband 0.7 (links point to the 0.7.3 docs); the crate is still pre-1.0, so later versions may require some adjustment.</em></p>
<p>Asyncband ships a wide box of coordination primitives: locks, channels, latches, pools. Wide enough that the daily question is rarely "how do I use X" but "which X is this job". This post walks the three you will reach for most often — <a href="https://docs.rs/asyncband/0.7.3/asyncband/semaphore/struct.Semaphore.html" target="_blank" rel="noopener noreferrer" class=""><code>Semaphore</code></a>, <a href="https://docs.rs/asyncband/0.7.3/asyncband/event/struct.ManualResetEvent.html" target="_blank" rel="noopener noreferrer" class=""><code>ManualResetEvent</code></a>, and <a href="https://docs.rs/asyncband/0.7.3/asyncband/event/struct.AutoResetEvent.html" target="_blank" rel="noopener noreferrer" class=""><code>AutoResetEvent</code></a> — through one question: <strong>what is the unit of coordination?</strong> A permit to count, a level to observe, or an edge to consume.</p>
<h2 class="anchor anchorTargetStickyNavbar_zq6S" id="count-when-you-bound-work">Count when you bound work<a href="https://asyncband.apache.org/blog/2026/10/14/choosing-the-right-primitive/#count-when-you-bound-work" class="hash-link" aria-label="Direct link to Count when you bound work" title="Direct link to Count when you bound work" translate="no">​</a></h2>
<p>A semaphore's state is a <em>number</em>. You reach for it when your condition is "no more than N of these at once": concurrent requests against one backend, buffers in flight, tasks sharing a scarce resource.</p>
<div class="language-rust codeBlockContainer_lkHg theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_KnrP"><pre tabindex="0" class="prism-code language-rust codeBlock_FDzL thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_pYqn"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">asyncband</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">semaphore</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Semaphore</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">handle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">socket</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Socket</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> limiter</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token class-name">Semaphore</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// At most `limiter` handlers run at once; the others wait</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// without blocking a thread.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> _permit </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">acquire</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    socket</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">serve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Dropping the permit releases it, and the next waiter proceeds.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The returned guard is the whole accounting story: acquire to enter, drop to leave, and the count stays consistent even if a task panics or is cancelled mid-work.</p>
<h2 class="anchor anchorTargetStickyNavbar_zq6S" id="signal-when-you-notify">Signal when you notify<a href="https://asyncband.apache.org/blog/2026/10/14/choosing-the-right-primitive/#signal-when-you-notify" class="hash-link" aria-label="Direct link to Signal when you notify" title="Direct link to Signal when you notify" translate="no">​</a></h2>
<p>When your condition is not a number but a <em>fact</em>, counting permits is the wrong shape. Asyncband's events come in the two classic flavors, and the difference is how they treat state:</p>
<ul>
<li class=""><a href="https://docs.rs/asyncband/0.7.3/asyncband/event/struct.ManualResetEvent.html" target="_blank" rel="noopener noreferrer" class=""><code>ManualResetEvent</code></a> is a <em>level</em>. <code>set</code> releases every registered waiter and stays set — future waits pass immediately — until an explicit <code>reset</code>. Use it as a readiness gate: configuration loaded, connection established, shutdown initiated.</li>
<li class=""><a href="https://docs.rs/asyncband/0.7.3/asyncband/event/struct.AutoResetEvent.html" target="_blank" rel="noopener noreferrer" class=""><code>AutoResetEvent</code></a> is an <em>edge</em>. Each <code>set</code> delivers one signal to one waiter; if nobody is waiting, one signal is retained. Bursts coalesce: three sets with no consumer in between leave one stored signal, not three.</li>
</ul>
<p>The clearest way to feel the difference is a workload that screams "queue" at first glance: a single worker that rebuilds a snapshot whenever a new revision is requested. Revisions arrive in bursts, but only the latest one matters — processing each intermediate revision would be wasted work. That rules out a channel: a channel's contract is that every sent value is delivered, which is exactly the work you want to <em>avoid</em>. A <code>ManualResetEvent</code> is also wrong: it would wake every consumer and stay set until reset, which is the wrong granularity for "something changed, re-check once".</p>
<p>An <code>AutoResetEvent</code> plus an atomic for the latest revision fits:</p>
<div class="language-rust codeBlockContainer_lkHg theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_KnrP"><pre tabindex="0" class="prism-code language-rust codeBlock_FDzL thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_pYqn"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">std</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">sync</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">atomic</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">AtomicUsize</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">std</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">sync</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">atomic</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">Ordering</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">use</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">asyncband</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">event</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">AutoResetEvent</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Rebuilder</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    requested</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">AtomicUsize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    changed</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">AutoResetEvent</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">Rebuilder</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">request</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> revision</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">usize</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">requested</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">fetch_max</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">revision</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name">Ordering</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Release</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">changed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">mut</span><span class="token plain"> rebuilt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">loop</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> requested </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">requested</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Ordering</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Acquire</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> requested </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> rebuilt </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token function" style="color:#d73a49">rebuild</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">requested</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// a burst of 1, 2, 3 coalesces into "rebuild 3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                rebuilt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> requested</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">changed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">wait</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Many producers call <code>request</code>; one consumer wakes, observes the <em>latest</em> state, and sleeps again. A signal that arrives between the state check and the wait is retained, so the worker cannot miss a change, and a leftover signal costs at most one extra predicate check. (This pattern is adapted from the <code>coalesced_worker</code> example in the <a href="https://github.com/apache/asyncband/tree/main/examples" target="_blank" rel="noopener noreferrer" class="">asyncband repository</a> — worth a read in full.)</p>
<h2 class="anchor anchorTargetStickyNavbar_zq6S" id="the-sharp-edges-of-counting">The sharp edges of counting<a href="https://asyncband.apache.org/blog/2026/10/14/choosing-the-right-primitive/#the-sharp-edges-of-counting" class="hash-link" aria-label="Direct link to The sharp edges of counting" title="Direct link to The sharp edges of counting" translate="no">​</a></h2>
<p>Semaphores look like the simplest primitive in the box, and most of the time they are. Four behaviors are worth internalizing before you build on them — all verified against the current implementation:</p>
<p><strong>An acquisition larger than the semaphore can ever grant never completes.</strong> Permits arrive only when someone releases them. <code>acquire(5)</code> against a semaphore initialized with 3 and never topped up waits forever. Unlike a channel, there is no "closed" state that fails the wait; the caller owns the timeout.</p>
<p><strong>Pending acquisitions complete in request order, and a big one at the head holds back smaller ones behind it.</strong> Permits are assigned to the queue head first. A partially satisfied <code>acquire(100)</code> keeps its place in line, so a stream of <code>acquire(1)</code> callers queued behind it waits until the big acquisition completes. This is fair — nobody jumps the line, and <code>try_acquire</code> cannot steal a handoff already assigned to a waiter — but if you mix sizes on one semaphore, mind the ordering interaction. One semaphore per size class avoids the coupling entirely.</p>
<p><strong>Cancelling a pending acquisition passes its credit forward.</strong> Wrap <code>acquire</code> in a timeout or <code>select!</code> and the cancelled future returns the permits <em>already assigned to it</em> to the next queued waiters — not to the available count. Nothing is lost and nothing leaks; the place in line is what you give up. So a timeout like this is always safe on the semaphore side:</p>
<div class="language-rust codeBlockContainer_lkHg theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_KnrP"><pre tabindex="0" class="prism-code language-rust codeBlock_FDzL thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_pYqn"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">match</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">tokio</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token namespace" style="opacity:0.7">time</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token function" style="color:#d73a49">timeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Duration</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">from_secs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sem</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">acquire</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permit</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">serve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">permit</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_elapsed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Any of the 5 permits already credited to us went to the</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// next waiter, not back to the pool. Nothing leaked.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p><strong><code>drain_permits</code> and <code>reduce_permits</code> shrink by different rules.</strong> <a href="https://docs.rs/asyncband/0.7.3/asyncband/semaphore/struct.Semaphore.html#method.drain_permits" target="_blank" rel="noopener noreferrer" class=""><code>drain_permits(n)</code></a> removes up to <code>n</code> <em>currently available</em> permits and never creates a deficit; <a href="https://docs.rs/asyncband/0.7.3/asyncband/semaphore/struct.Semaphore.html#method.reduce_permits" target="_blank" rel="noopener noreferrer" class=""><code>reduce_permits(n)</code></a> removes exactly <code>n</code>, consuming future releases when fewer are available — those releases repay the deficit before any queued acquisition proceeds. Drain when you observe; reduce when you permanently remove capacity.</p>
<h2 class="anchor anchorTargetStickyNavbar_zq6S" id="where-to-go-next">Where to go next<a href="https://asyncband.apache.org/blog/2026/10/14/choosing-the-right-primitive/#where-to-go-next" class="hash-link" aria-label="Direct link to Where to go next" title="Direct link to Where to go next" translate="no">​</a></h2>
<p>The <a href="https://docs.rs/asyncband/" target="_blank" rel="noopener noreferrer" class="">API documentation</a> covers each primitive's ordering, cancellation, and memory-model contracts in detail, and the <a href="https://github.com/apache/asyncband/tree/main/examples" target="_blank" rel="noopener noreferrer" class="">examples crate</a> demonstrates the patterns above as complete runnable programs.</p>]]></content>
        <author>
            <name>Nanami</name>
            <uri>https://github.com/nanami-0713</uri>
        </author>
        <category label="async rust" term="async rust"/>
        <category label="concurrency" term="concurrency"/>
    </entry>
</feed>