<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://clustron.io/blog/</id>
    <title>Clustron Blog</title>
    <updated>2026-03-30T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://clustron.io/blog/"/>
    <subtitle>Clustron Blog</subtitle>
    <icon>https://clustron.io/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Build Reactive Systems with Clustron Watch]]></title>
        <id>https://clustron.io/blog/2026/03/30/watch-changes/</id>
        <link href="https://clustron.io/blog/2026/03/30/watch-changes/"/>
        <updated>2026-03-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Most distributed systems don’t start out complicated.]]></summary>
        <content type="html"><![CDATA[<p>Most distributed systems don’t start out complicated.</p>
<p>They begin with something simple — a loop.</p>
<p>You write a small worker that checks for work:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> job </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token generic-method function" style="color:#d73a49">GetAsync</span><span class="token generic-method generic class-name punctuation" style="color:#393A34">&lt;</span><span class="token generic-method generic class-name">Job</span><span class="token generic-method generic class-name punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"jobs:next"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">IsSuccess</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">ProcessAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">job</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> Task</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Delay</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>At this stage, everything feels reasonable. The logic is clear, the system behaves predictably, and there is very little cognitive overhead.</p>
<p>But as the system grows, this pattern quietly becomes one of the most expensive parts of your architecture.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-hidden-cost-of-polling-in-distributed-systems">The Hidden Cost of Polling in Distributed Systems<a href="https://clustron.io/blog/2026/03/30/watch-changes/#the-hidden-cost-of-polling-in-distributed-systems" class="hash-link" aria-label="Direct link to The Hidden Cost of Polling in Distributed Systems" title="Direct link to The Hidden Cost of Polling in Distributed Systems" translate="no">​</a></h2>
<p>Polling introduces a fundamental inefficiency: you are repeatedly asking the system for changes that usually haven’t happened.</p>
<p>As you scale:</p>
<ul>
<li class="">Multiple instances begin polling the same data</li>
<li class="">Each instance performs repeated reads, most of which return no useful information</li>
<li class="">You introduce artificial latency — changes are only detected on the next polling cycle</li>
<li class="">The system starts consuming resources simply to confirm that nothing has changed</li>
</ul>
<p>This leads to a system that is technically correct, but operationally inefficient.</p>
<p>More importantly, polling forces you to make tradeoffs you shouldn’t have to make:</p>
<ul>
<li class="">Poll frequently → higher cost, lower latency</li>
<li class="">Poll less frequently → lower cost, higher latency</li>
</ul>
<p>There is no correct answer — only compromise.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-different-model-reacting-instead-of-asking">A Different Model: Reacting Instead of Asking<a href="https://clustron.io/blog/2026/03/30/watch-changes/#a-different-model-reacting-instead-of-asking" class="hash-link" aria-label="Direct link to A Different Model: Reacting Instead of Asking" title="Direct link to A Different Model: Reacting Instead of Asking" translate="no">​</a></h2>
<p>The alternative is not just an optimization — it is a different way of thinking about systems.</p>
<p>Instead of asking:</p>
<blockquote>
<p>“Has something changed?”</p>
</blockquote>
<p>You design your system to respond to:</p>
<blockquote>
<p>“Something just changed.”</p>
</blockquote>
<p>This is the shift from a <strong>pull-based model</strong> to a <strong>push-based model</strong>.</p>
<p>In Clustron, this is implemented through Watch.</p>
<hr>
<p><img decoding="async" loading="lazy" alt="Polling model vs watching changes" src="https://clustron.io/assets/images/diagram-ee01eb60798fc51fb1c3beef2a907c7e.png" width="1536" height="1024" class="img_ev3q"></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introducing-watch-a-stream-of-state-changes">Introducing Watch: A Stream of State Changes<a href="https://clustron.io/blog/2026/03/30/watch-changes/#introducing-watch-a-stream-of-state-changes" class="hash-link" aria-label="Direct link to Introducing Watch: A Stream of State Changes" title="Direct link to Introducing Watch: A Stream of State Changes" translate="no">​</a></h2>
<p>Clustron Watch allows you to subscribe to changes in the system and receive events as they happen.</p>
<p>At its core, Watch turns your data into a <strong>continuous stream of updates</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="watching-a-single-key">Watching a Single Key<a href="https://clustron.io/blog/2026/03/30/watch-changes/#watching-a-single-key" class="hash-link" aria-label="Direct link to Watching a Single Key" title="Direct link to Watching a Single Key" translate="no">​</a></h3>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">subscription</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> initialRecord</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Watch</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WatchKeyAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"order:1001"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name">WatchOptions</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> IncludeInitialSnapshot </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ev </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">ev</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">EventType</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c"> → </span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">ev</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">Key</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c"> = </span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">ev</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">Value</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </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><br></span></code></pre></div></div>
<p>This does two important things:</p>
<ol>
<li class="">It gives you the current state (<code>initialRecord</code>)</li>
<li class="">It subscribes you to all future changes</li>
</ol>
<p>This combination is critical. Without it, you would have to manually fetch the current value and then subscribe — which introduces race conditions.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="snapshot--streaming-a-correctness-guarantee">Snapshot + Streaming: A Correctness Guarantee<a href="https://clustron.io/blog/2026/03/30/watch-changes/#snapshot--streaming-a-correctness-guarantee" class="hash-link" aria-label="Direct link to Snapshot + Streaming: A Correctness Guarantee" title="Direct link to Snapshot + Streaming: A Correctness Guarantee" translate="no">​</a></h2>
<p>One of the subtle but essential aspects of Watch is the ability to include an initial snapshot.</p>
<p>When <code>IncludeInitialSnapshot</code> is enabled:</p>
<ul>
<li class="">You receive the current value at the time of subscription</li>
<li class="">You then receive all subsequent updates in order</li>
</ul>
<p>This ensures that:</p>
<ul>
<li class="">You do not miss existing state</li>
<li class="">You do not miss future changes</li>
<li class="">You do not need additional synchronization logic</li>
</ul>
<p>In other words, Watch provides a <strong>complete and consistent view of state evolution</strong>.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="watching-collections-moving-beyond-single-keys">Watching Collections: Moving Beyond Single Keys<a href="https://clustron.io/blog/2026/03/30/watch-changes/#watching-collections-moving-beyond-single-keys" class="hash-link" aria-label="Direct link to Watching Collections: Moving Beyond Single Keys" title="Direct link to Watching Collections: Moving Beyond Single Keys" translate="no">​</a></h2>
<p>While watching a single key is useful, most real systems operate on groups of related data.</p>
<p>Clustron supports this through prefix-based watching:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> subscription </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Watch</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WatchPrefixAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"jobs:"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name">WatchOptions</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> IncludeInitialSnapshot </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ev </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"Job update: </span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">ev</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">Key</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </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><br></span></code></pre></div></div>
<p>This allows you to observe all changes within a logical group.</p>
<p>From an architectural perspective, this is where Watch becomes significantly more powerful:</p>
<ul>
<li class="">You are no longer reacting to individual values</li>
<li class="">You are reacting to <strong>system-wide state transitions</strong></li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="understanding-the-event-model">Understanding the Event Model<a href="https://clustron.io/blog/2026/03/30/watch-changes/#understanding-the-event-model" class="hash-link" aria-label="Direct link to Understanding the Event Model" title="Direct link to Understanding the Event Model" translate="no">​</a></h2>
<p>Each change in the system produces a <code>WatchEvent</code>.</p>
<p>A typical event contains:</p>
<ul>
<li class="">The key that changed</li>
<li class="">The type of change (<code>Put</code> or <code>Delete</code>)</li>
<li class="">The new value (if applicable)</li>
<li class="">A revision representing the version of the change</li>
</ul>
<p>This revision is particularly important. It provides ordering and allows you to reason about the sequence of events across a distributed system.</p>
<p>Effectively, Watch gives you a <strong>log of state transitions</strong>, delivered in real time.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-this-enables-in-practice">What This Enables in Practice<a href="https://clustron.io/blog/2026/03/30/watch-changes/#what-this-enables-in-practice" class="hash-link" aria-label="Direct link to What This Enables in Practice" title="Direct link to What This Enables in Practice" translate="no">​</a></h2>
<p>Once you adopt this model, several common problems become simpler.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="job-processing">Job Processing<a href="https://clustron.io/blog/2026/03/30/watch-changes/#job-processing" class="hash-link" aria-label="Direct link to Job Processing" title="Direct link to Job Processing" translate="no">​</a></h3>
<p>Instead of polling for new work, workers react immediately when jobs are created or updated.</p>
<p>This removes idle cycles and reduces latency.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cache-invalidation">Cache Invalidation<a href="https://clustron.io/blog/2026/03/30/watch-changes/#cache-invalidation" class="hash-link" aria-label="Direct link to Cache Invalidation" title="Direct link to Cache Invalidation" translate="no">​</a></h3>
<p>Rather than relying on TTL or periodic refresh, caches can update themselves in response to actual changes.</p>
<p>This improves both freshness and efficiency.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="distributed-coordination">Distributed Coordination<a href="https://clustron.io/blog/2026/03/30/watch-changes/#distributed-coordination" class="hash-link" aria-label="Direct link to Distributed Coordination" title="Direct link to Distributed Coordination" translate="no">​</a></h3>
<p>Systems that rely on shared state — such as leader election or lease ownership — benefit significantly from real-time updates.</p>
<p>Changes propagate instantly, allowing faster and more reliable coordination.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="presence-and-monitoring">Presence and Monitoring<a href="https://clustron.io/blog/2026/03/30/watch-changes/#presence-and-monitoring" class="hash-link" aria-label="Direct link to Presence and Monitoring" title="Direct link to Presence and Monitoring" translate="no">​</a></h3>
<p>Tracking active components becomes trivial:</p>
<ul>
<li class="">When a node appears → you receive an event</li>
<li class="">When a node disappears → you receive an event</li>
</ul>
<p>No polling, no guessing.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="operational-considerations">Operational Considerations<a href="https://clustron.io/blog/2026/03/30/watch-changes/#operational-considerations" class="hash-link" aria-label="Direct link to Operational Considerations" title="Direct link to Operational Considerations" translate="no">​</a></h2>
<p>Watch is designed for long-running, event-driven workloads.</p>
<p>A few important considerations:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="keep-handlers-lightweight">Keep Handlers Lightweight<a href="https://clustron.io/blog/2026/03/30/watch-changes/#keep-handlers-lightweight" class="hash-link" aria-label="Direct link to Keep Handlers Lightweight" title="Direct link to Keep Handlers Lightweight" translate="no">​</a></h3>
<p>Your event handler should not perform heavy work directly.</p>
<p>Instead:</p>
<ul>
<li class="">Process quickly</li>
<li class="">Delegate heavier tasks to background workers</li>
</ul>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="manage-subscription-lifecycle">Manage Subscription Lifecycle<a href="https://clustron.io/blog/2026/03/30/watch-changes/#manage-subscription-lifecycle" class="hash-link" aria-label="Direct link to Manage Subscription Lifecycle" title="Direct link to Manage Subscription Lifecycle" translate="no">​</a></h3>
<p>Always stop subscriptions when they are no longer needed:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> subscription</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">StopAsync</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><br></span></code></pre></div></div>
<p>This ensures resources are released cleanly.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="understand-scope">Understand Scope<a href="https://clustron.io/blog/2026/03/30/watch-changes/#understand-scope" class="hash-link" aria-label="Direct link to Understand Scope" title="Direct link to Understand Scope" translate="no">​</a></h3>
<ul>
<li class="">Watching a key → only that key produces events</li>
<li class="">Watching a prefix → only matching keys produce events</li>
</ul>
<p>Events are scoped and isolated, which prevents unintended cross-talk between components.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="from-polling-loops-to-reactive-systems">From Polling Loops to Reactive Systems<a href="https://clustron.io/blog/2026/03/30/watch-changes/#from-polling-loops-to-reactive-systems" class="hash-link" aria-label="Direct link to From Polling Loops to Reactive Systems" title="Direct link to From Polling Loops to Reactive Systems" translate="no">​</a></h2>
<p>The shift from polling to watching is not just about performance.</p>
<p>It changes the structure of your application.</p>
<p>Polling systems are built around:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Loop → Check → Wait → Repeat</span><br></span></code></pre></div></div>
<p>Reactive systems are built around:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Event → Handler → Action</span><br></span></code></pre></div></div>
<p>This results in systems that are:</p>
<ul>
<li class="">More responsive</li>
<li class="">More efficient</li>
<li class="">Easier to reason about</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="final-thoughts">Final Thoughts<a href="https://clustron.io/blog/2026/03/30/watch-changes/#final-thoughts" class="hash-link" aria-label="Direct link to Final Thoughts" title="Direct link to Final Thoughts" translate="no">​</a></h2>
<p>Polling is often the simplest way to get started, and in small systems, it works well enough.</p>
<p>But as systems grow, the cost of polling becomes increasingly difficult to justify.</p>
<p>Clustron Watch offers a different approach — one where your system reacts to change rather than searching for it.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Stop asking your system if something changed.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Let it tell you when it does.</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="getting-started">Getting Started<a href="https://clustron.io/blog/2026/03/30/watch-changes/#getting-started" class="hash-link" aria-label="Direct link to Getting Started" title="Direct link to Getting Started" translate="no">​</a></h2>
<p>Try a simple watch:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Watch</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WatchPrefixAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"orders:"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ev </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">ev</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">Key</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c"> updated"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></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><br></span></code></pre></div></div>
<p>From there, start removing polling loops — one at a time.</p>
<p>You’ll quickly find that your system becomes not just faster, but fundamentally simpler.</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[Distributed Caching in .NET]]></title>
        <id>https://clustron.io/blog/2026/03/16/distributed-caching-dotnet/</id>
        <link href="https://clustron.io/blog/2026/03/16/distributed-caching-dotnet/"/>
        <updated>2026-03-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn how distributed caching works in .NET, why it is required for scalable systems, and how to implement it using modern distributed key-value platforms.]]></summary>
        <content type="html"><![CDATA[<p>Caching is one of the most effective ways to improve the performance of
an application.<br>
<!-- -->Most .NET applications start with a simple in‑memory cache using
<code>MemoryCache</code> or <code>IMemoryCache</code>. This works perfectly when the
application runs on a single server.</p>
<p>However, modern applications rarely run on a single machine.</p>
<p>When applications scale horizontally across multiple instances,
in‑memory caching stops working reliably. Each instance maintains its
own cache, which means the application state becomes inconsistent across
the cluster.</p>
<p>This is where <strong>distributed caching</strong> becomes essential.</p>
<hr>
<p><img decoding="async" loading="lazy" alt="Distributed Cache" src="https://clustron.io/assets/images/distributed-cache-9c612c5d1942f64f2a7658cbc897a310.png" width="1536" height="1024" class="img_ev3q"></p>
<hr>
<h1>The Problem with In‑Memory Caches</h1>
<p>Consider a typical ASP.NET application deployed behind a load balancer.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">          Load Balancer</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                |</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     ---------------------------</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     |            |            |</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Server A     Server B     Server C</span><br></span></code></pre></div></div>
<p>Each server has its own memory cache.</p>
<p>If a request updates cached data on <strong>Server A</strong>, the caches on <strong>Server
B</strong> and <strong>Server C</strong> remain outdated.</p>
<p>This leads to several problems:</p>
<ul>
<li class="">inconsistent application state</li>
<li class="">stale cache entries</li>
<li class="">duplicate cache warmups</li>
<li class="">unpredictable behavior</li>
</ul>
<p>To solve this problem, the cache must be <strong>shared across all nodes</strong>.</p>
<hr>
<h1>What is a Distributed Cache?</h1>
<p>A distributed cache is a <strong>centralized or clustered cache</strong> that can be
accessed by multiple application instances.</p>
<p>Instead of storing cached data inside the application process, the data
is stored in a <strong>distributed key‑value store</strong>.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">           Application Nodes</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        App A     App B     App C</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          |         |         |</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          +---------+---------+</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    |</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            Distributed Cache</span><br></span></code></pre></div></div>
<p>All application nodes read and write cache entries from the same
distributed store.</p>
<p>This ensures:</p>
<ul>
<li class="">consistent cached data</li>
<li class="">shared application state</li>
<li class="">better scalability</li>
</ul>
<hr>
<h1>Basic Distributed Cache Example in .NET</h1>
<p>A distributed cache is typically used through an abstraction such as
<code>IDistributedCache</code>.</p>
<p>Example:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">ProductService</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">readonly</span><span class="token plain"> </span><span class="token class-name">IDistributedCache</span><span class="token plain"> _cache</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">ProductService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">IDistributedCache</span><span class="token plain"> cache</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        _cache </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> cache</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token return-type class-name">Task</span><span class="token return-type class-name punctuation" style="color:#393A34">&lt;</span><span class="token return-type class-name keyword" style="color:#00009f">string</span><span class="token return-type class-name punctuation" style="color:#393A34">?</span><span class="token return-type class-name punctuation" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">GetProductAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name keyword" style="color:#00009f">string</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> cached </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> _cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">GetStringAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cached </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> cached</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> product </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">LoadProductFromDatabase</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> _cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetStringAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> product</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> product</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token return-type class-name">Task</span><span class="token return-type class-name punctuation" style="color:#393A34">&lt;</span><span class="token return-type class-name keyword" style="color:#00009f">string</span><span class="token return-type class-name punctuation" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">LoadProductFromDatabase</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name keyword" style="color:#00009f">string</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> Task</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromResult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"Product </span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">id</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>The application first checks the cache. If the value is missing, the
data is loaded from the database and then stored in the cache.</p>
<p>This pattern is called <strong>cache‑aside caching</strong>.</p>
<hr>
<h1>Common Distributed Cache Solutions</h1>
<p>Several technologies provide distributed caching capabilities.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="redis">Redis<a href="https://clustron.io/blog/2026/03/16/distributed-caching-dotnet/#redis" class="hash-link" aria-label="Direct link to Redis" title="Direct link to Redis" translate="no">​</a></h2>
<p>Redis is one of the most widely used distributed caches.</p>
<p>It provides:</p>
<ul>
<li class="">key‑value storage</li>
<li class="">high performance</li>
<li class="">in‑memory operations</li>
</ul>
<p>However, Redis often requires additional components when used for
distributed coordination.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="databasebacked-caches">Database‑Backed Caches<a href="https://clustron.io/blog/2026/03/16/distributed-caching-dotnet/#databasebacked-caches" class="hash-link" aria-label="Direct link to Database‑Backed Caches" title="Direct link to Database‑Backed Caches" translate="no">​</a></h2>
<p>Some applications use relational databases as caches.</p>
<p>While simple, this approach introduces:</p>
<ul>
<li class="">database contention</li>
<li class="">reduced performance</li>
<li class="">limited scalability</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="distributed-keyvalue-platforms">Distributed Key‑Value Platforms<a href="https://clustron.io/blog/2026/03/16/distributed-caching-dotnet/#distributed-keyvalue-platforms" class="hash-link" aria-label="Direct link to Distributed Key‑Value Platforms" title="Direct link to Distributed Key‑Value Platforms" translate="no">​</a></h2>
<p>Modern distributed systems often use <strong>distributed key‑value platforms</strong>
that provide both caching and coordination primitives.</p>
<p>These systems support:</p>
<ul>
<li class="">distributed caching</li>
<li class="">distributed locks</li>
<li class="">leader election</li>
<li class="">change notifications</li>
<li class="">cluster coordination</li>
</ul>
<hr>
<h1>Using Clustron as a Distributed Cache</h1>
<p>Clustron provides a distributed key‑value platform designed for .NET
applications.</p>
<p>Because it runs as a distributed cluster, all application instances
interact with the same shared data store.</p>
<p>Example:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">using</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">Clustron</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">.</span><span class="token namespace" style="opacity:0.7">DKV</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">.</span><span class="token namespace" style="opacity:0.7">Client</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> client </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> DKVClient</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">InitializeRemote</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"teststore"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">new</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name">DkvServerInfo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"localhost"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7861</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">PutAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"product:1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Laptop"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token generic-method function" style="color:#d73a49">GetAsync</span><span class="token generic-method generic class-name punctuation" style="color:#393A34">&lt;</span><span class="token generic-method generic class-name keyword" style="color:#00009f">string</span><span class="token generic-method generic class-name punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"product:1"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>In this example:</p>
<ul>
<li class="">application nodes connect to the cluster</li>
<li class="">data is stored in the distributed store</li>
<li class="">all nodes see the same data</li>
</ul>
<p>This allows the cache to remain <strong>consistent across the entire
cluster</strong>.</p>
<hr>
<h1>When to Use Distributed Caching</h1>
<p>Distributed caching is especially useful in systems that:</p>
<ul>
<li class="">run multiple application instances</li>
<li class="">process high request volumes</li>
<li class="">rely heavily on database reads</li>
<li class="">require shared application state</li>
</ul>
<p>Typical use cases include:</p>
<ul>
<li class="">ASP.NET web applications</li>
<li class="">microservices architectures</li>
<li class="">background processing systems</li>
<li class="">API platforms</li>
</ul>
<hr>
<h1>Summary</h1>
<p>In‑memory caching works well for single‑server applications, but modern
distributed systems require a shared caching layer.</p>
<p>Distributed caching allows multiple application instances to share the
same cached data, improving scalability and consistency.</p>
<p>Platforms such as Clustron provide a distributed key‑value store that
makes it easy to implement distributed caching and coordination in .NET
applications.</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[Leader Election in Distributed Systems]]></title>
        <id>https://clustron.io/blog/2026/03/14/leader-election-dotnet/</id>
        <link href="https://clustron.io/blog/2026/03/14/leader-election-dotnet/"/>
        <updated>2026-03-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn how leader election works in distributed systems and how to implement it in .NET using lease-based coordination patterns.]]></summary>
        <content type="html"><![CDATA[<p>When applications scale across multiple machines, coordination becomes
one of the hardest problems to solve.<br>
<!-- -->Distributed systems often run several identical nodes that can all
perform the same work. Without coordination, those nodes may attempt the
same task simultaneously, leading to duplicate work, race conditions, or
inconsistent state.</p>
<p>One of the most common ways to solve this problem is <strong>leader
election</strong>.</p>
<p>Leader election ensures that <strong>one node temporarily becomes the leader</strong>
while the other nodes remain followers. The leader performs coordination
tasks while followers wait for leadership to change.</p>
<p>This pattern is widely used in distributed databases, job schedulers,
container orchestration platforms, and configuration systems.</p>
<hr>
<p><img decoding="async" loading="lazy" alt="Leader Election in Distributed Systems" src="https://clustron.io/assets/images/leader-election-e545fea3ee2bf5177ec0cc4d1b413847.png" width="1024" height="1536" class="img_ev3q"></p>
<hr>
<h1>A Simple Example</h1>
<p>Imagine a distributed worker system with three nodes:</p>
<p>Worker A
Worker B
Worker C</p>
<p>Each worker is capable of running background jobs.</p>
<p>If all workers execute the same scheduled job, the job will run three
times.<br>
<!-- -->Instead, we want <strong>exactly one worker to run the job</strong>.</p>
<p>This is where leader election becomes useful. One worker becomes the
<strong>leader</strong>, and only the leader runs the job.</p>
<hr>
<h1>The Simplest Leader Election Pattern</h1>
<p>A common approach uses a <strong>shared coordination store</strong>.</p>
<p>The idea is simple:</p>
<ol>
<li class="">Each node attempts to acquire leadership.</li>
<li class="">The node that succeeds becomes the leader.</li>
<li class="">The leader periodically renews its leadership.</li>
<li class="">If the leader fails, another node takes over.</li>
</ol>
<p>This is typically implemented using a <strong>lease</strong>.</p>
<p>A lease acts like a lock with an expiration time. If the node holding
the lease disappears, another node can safely acquire leadership.</p>
<hr>
<h1>A Minimal .NET Example</h1>
<p>The following simplified example demonstrates the idea behind
lease-based leadership.</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">LeaderElection</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">readonly</span><span class="token plain"> </span><span class="token class-name">ILeaseStore</span><span class="token plain"> _store</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">readonly</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">string</span><span class="token plain"> _nodeId</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">LeaderElection</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">ILeaseStore</span><span class="token plain"> store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">string</span><span class="token plain"> nodeId</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        _store </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> store</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        _nodeId </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> nodeId</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token return-type class-name">Task</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">RunAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> acquired </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> _store</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">TryAcquireLeaseAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"cluster-leader"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _nodeId</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> TimeSpan</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromSeconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">acquired</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">                Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">_nodeId</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c"> is leader"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">PerformLeaderWork</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> _store</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">RenewLeaseAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"cluster-leader"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _nodeId</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> Task</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Delay</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token return-type class-name">Task</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">PerformLeaderWork</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Running scheduled tasks..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> Task</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CompletedTask</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>In this example:</p>
<ul>
<li class="">Every node attempts to acquire the lease <code>"cluster-leader"</code>.</li>
<li class="">The node that succeeds becomes the leader.</li>
<li class="">The leader periodically renews the lease.</li>
<li class="">If the leader crashes, the lease expires and another node takes
over.</li>
</ul>
<p>This pattern provides <strong>automatic failover</strong>.</p>
<hr>
<h1>Problems with DIY Leader Election</h1>
<p>Although the example above looks simple, real-world distributed systems
introduce complications:</p>
<p>Network partitions can cause nodes to believe they are still leaders.</p>
<p>Clock drift may cause lease expiration problems.</p>
<p>Slow failure detection may delay leadership transfer.</p>
<p>Building a robust leader election mechanism requires careful handling of
distributed systems edge cases.</p>
<p>This is why many systems rely on <strong>specialized coordination platforms</strong>
such as:</p>
<ul>
<li class="">etcd</li>
<li class="">ZooKeeper</li>
<li class="">Consul</li>
</ul>
<p>These systems implement reliable coordination primitives.</p>
<hr>
<h1>Leader Election with Clustron</h1>
<p>Clustron provides a clustering platform for distributed systems in .NET.</p>
<p>Instead of building coordination infrastructure yourself, applications
can use the platform's built-in primitives.</p>
<p>Example using Clustron's lease concept:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">using</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">Clustron</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">.</span><span class="token namespace" style="opacity:0.7">DKV</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">.</span><span class="token namespace" style="opacity:0.7">Client</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> client </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> DKVClient</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">InitializeRemote</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"teststore"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">new</span><span class="token punctuation" style="color:#393A34">[</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><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name">DkvServerInfo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"localhost"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7861</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 punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> lease </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">GrantLeaseAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">TimeSpan</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromSeconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lease</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Acquired</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"This node is the leader."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">RefreshLeaseAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lease</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> Task</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Delay</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Here the node requests a <strong>lease from the cluster</strong>.</p>
<p>If the lease is granted, the node becomes the leader.<br>
<!-- -->As long as the node keeps refreshing the lease, leadership remains
valid.</p>
<p>If the node crashes or stops renewing the lease, another node can
acquire leadership automatically.</p>
<hr>
<h1>When Leader Election Is Useful</h1>
<p>Leader election appears in many real-world distributed systems:</p>
<ul>
<li class="">Distributed job schedulers</li>
<li class="">Background task processors</li>
<li class="">Cluster managers</li>
<li class="">Microservice coordination</li>
<li class="">Configuration controllers</li>
</ul>
<p>Any time a system requires <strong>exactly one node to coordinate activity</strong>,
leader election becomes essential.</p>
<hr>
<h1>Summary</h1>
<p>Leader election is a fundamental building block for distributed systems.</p>
<p>It allows clusters of nodes to coordinate their behavior while
maintaining high availability.</p>
<p>A lease-based approach provides a simple and effective implementation
strategy, and distributed platforms such as Clustron make these
primitives available directly to .NET applications.</p>
<p>Instead of building coordination logic from scratch, developers can
focus on application behavior while the clustering platform handles
leadership, failover, and coordination.</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[Distributed Locks Explained]]></title>
        <id>https://clustron.io/blog/distributed-locks-explained/</id>
        <link href="https://clustron.io/blog/distributed-locks-explained/"/>
        <updated>2026-03-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A Practical Guide for .NET Developers]]></summary>
        <content type="html"><![CDATA[<p><em>A Practical Guide for .NET Developers</em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://clustron.io/blog/distributed-locks-explained/#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>As applications scale across multiple machines, coordination becomes one
of the most challenging aspects of system design.</p>
<p>In a single-machine application, mutual exclusion is straightforward.
Developers can rely on language primitives such as <code>lock</code> in C#,
<code>Mutex</code>, or <code>Semaphore</code> to ensure that only one thread accesses a shared
resource at a time.</p>
<p>However, these primitives only work <strong>within a single process or
machine</strong>.</p>
<p>Once applications run across multiple services or nodes, traditional
locking mechanisms no longer work. Two services running on different
machines cannot rely on a local <code>lock</code> statement to coordinate access to
shared state.</p>
<p>This is where <strong>distributed locks</strong> become essential.</p>
<p>Distributed locks allow services across a cluster to coordinate access
to shared resources while ensuring that only one participant holds the
lock at a given time.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="local-locks-vs-distributed-locks">Local Locks vs Distributed Locks<a href="https://clustron.io/blog/distributed-locks-explained/#local-locks-vs-distributed-locks" class="hash-link" aria-label="Direct link to Local Locks vs Distributed Locks" title="Direct link to Local Locks vs Distributed Locks" translate="no">​</a></h2>
<p>A typical local lock in C# looks like this:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">private</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">static</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">readonly</span><span class="token plain"> </span><span class="token class-name keyword" style="color:#00009f">object</span><span class="token plain"> _lock </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token constructor-invocation class-name keyword" style="color:#00009f">object</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">public</span><span class="token plain"> </span><span class="token return-type class-name keyword" style="color:#00009f">void</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">ProcessOrder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">lock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_lock</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">        Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Processing order safely."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>This works perfectly <strong>inside a single process</strong>.</p>
<p>However, if your application runs on <strong>multiple service instances</strong>,
each instance has its own <code>_lock</code> object. The lock no longer coordinates
work across the system.</p>
<p>Worker A → lock acquired
Worker B → lock acquired
Worker C → lock acquired</p>
<p>All workers proceed simultaneously, defeating the purpose of locking.</p>
<p>Distributed systems require a <strong>shared coordination mechanism</strong>.</p>
<hr>
<p><img decoding="async" loading="lazy" alt="Distributed Locking" src="https://clustron.io/assets/images/locks-explained-d18d3bec4a244049ab4b2423b54932ea.png" width="1536" height="1024" class="img_ev3q"></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-idea-behind-distributed-locks">The Idea Behind Distributed Locks<a href="https://clustron.io/blog/distributed-locks-explained/#the-idea-behind-distributed-locks" class="hash-link" aria-label="Direct link to The Idea Behind Distributed Locks" title="Direct link to The Idea Behind Distributed Locks" translate="no">​</a></h2>
<p>A distributed lock uses a <strong>shared system</strong> to represent lock ownership.</p>
<p>Instead of locking memory, a node records lock ownership in a
distributed coordination system such as:</p>
<ul>
<li class="">a distributed key‑value store</li>
<li class="">a coordination service</li>
<li class="">a distributed cache</li>
</ul>
<p>Example concept:</p>
<p>Lock Key: order:123
Owner: worker‑1</p>
<p>If another worker attempts to acquire the same lock, the operation fails
until the lock is released or expires.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="real-world-scenario-distributed-invoice-processing">Real World Scenario: Distributed Invoice Processing<a href="https://clustron.io/blog/distributed-locks-explained/#real-world-scenario-distributed-invoice-processing" class="hash-link" aria-label="Direct link to Real World Scenario: Distributed Invoice Processing" title="Direct link to Real World Scenario: Distributed Invoice Processing" translate="no">​</a></h2>
<p>Imagine a cluster of workers processing invoices.</p>
<p>Worker A
Worker B
Worker C</p>
<p>All workers scan for pending invoices.</p>
<p>Without locking:</p>
<p>Worker A → processes invoice #101
Worker B → processes invoice #101
Worker C → processes invoice #101</p>
<p>The same invoice could be processed multiple times.</p>
<p>A distributed lock ensures that <strong>only one worker processes the
invoice</strong>.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="distributed-locks-with-clustron-dkv">Distributed Locks with Clustron DKV<a href="https://clustron.io/blog/distributed-locks-explained/#distributed-locks-with-clustron-dkv" class="hash-link" aria-label="Direct link to Distributed Locks with Clustron DKV" title="Direct link to Distributed Locks with Clustron DKV" translate="no">​</a></h2>
<p>Clustron DKV provides built‑in primitives for distributed coordination.</p>
<p>Locks are managed through the <strong>Locks API</strong>, and operations on locked
keys must include the correct <strong>lock handle</strong>.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="acquiring-a-lock">Acquiring a Lock<a href="https://clustron.io/blog/distributed-locks-explained/#acquiring-a-lock" class="hash-link" aria-label="Direct link to Acquiring a Lock" title="Direct link to Acquiring a Lock" translate="no">​</a></h2>
<p>A client first acquires a lock for a specific key.</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> locks </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">IDkv</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">client</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Locks</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> key </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"order:123"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> lockHandle </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> locks</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AcquireAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> TimeSpan</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromSeconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lockHandle </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Failed to acquire lock."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Lock acquired."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>The returned <strong>lock handle</strong> represents ownership of the lock.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="performing-operations-under-the-lock">Performing Operations Under the Lock<a href="https://clustron.io/blog/distributed-locks-explained/#performing-operations-under-the-lock" class="hash-link" aria-label="Direct link to Performing Operations Under the Lock" title="Direct link to Performing Operations Under the Lock" translate="no">​</a></h2>
<p>Once a lock is acquired, operations must include the lock handle.</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">PutAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"processed"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Put</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WithLock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lockHandle</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Handle</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">IsSuccess</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Value updated safely."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Only the lock owner can modify the value.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reading-with-the-lock">Reading with the Lock<a href="https://clustron.io/blog/distributed-locks-explained/#reading-with-the-lock" class="hash-link" aria-label="Direct link to Reading with the Lock" title="Direct link to Reading with the Lock" translate="no">​</a></h2>
<p>Reads can also respect the lock ownership.</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">value</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token generic-method function" style="color:#d73a49">GetAsync</span><span class="token generic-method generic class-name punctuation" style="color:#393A34">&lt;</span><span class="token generic-method generic class-name keyword" style="color:#00009f">string</span><span class="token generic-method generic class-name punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    Get</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WithLock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lockHandle</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Handle</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">IsSuccess</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"Value: </span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp keyword" style="color:#00009f">value</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">Value</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="competing-operations-without-the-lock">Competing Operations Without the Lock<a href="https://clustron.io/blog/distributed-locks-explained/#competing-operations-without-the-lock" class="hash-link" aria-label="Direct link to Competing Operations Without the Lock" title="Direct link to Competing Operations Without the Lock" translate="no">​</a></h2>
<p>If another worker attempts to modify the key without the lock, the
operation fails.</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token class-name keyword" style="color:#00009f">var</span><span class="token plain"> attempt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">PutAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"new-value"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">attempt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">IsSuccess</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span 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></span><span class="token-line" style="color:#393A34"><span class="token plain">    Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token interpolation-string string" style="color:#e3116c">$"Operation rejected: </span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">{</span><span class="token interpolation-string interpolation expression language-csharp">attempt</span><span class="token interpolation-string interpolation expression language-csharp punctuation" style="color:#393A34">.</span><span class="token interpolation-string interpolation expression language-csharp">Status</span><span class="token interpolation-string interpolation punctuation" style="color:#393A34">}</span><span class="token interpolation-string string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Result:</p>
<p>KvStatus.Locked</p>
<p>This prevents concurrent modification of the same resource.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="releasing-the-lock">Releasing the Lock<a href="https://clustron.io/blog/distributed-locks-explained/#releasing-the-lock" class="hash-link" aria-label="Direct link to Releasing the Lock" title="Direct link to Releasing the Lock" translate="no">​</a></h2>
<p>Once the work is finished, the lock can be released.</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> lockHandle</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ReleaseAsync</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></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteLine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Lock released."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>After the lock is released, another worker may acquire it.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-cluster-workflow">Example Cluster Workflow<a href="https://clustron.io/blog/distributed-locks-explained/#example-cluster-workflow" class="hash-link" aria-label="Direct link to Example Cluster Workflow" title="Direct link to Example Cluster Workflow" translate="no">​</a></h2>
<p>Worker A → Acquire Lock → Success
Worker B → Acquire Lock → Failed
Worker C → Acquire Lock → Failed</p>
<p>Worker A → Update Key
Worker A → Release Lock</p>
<p>Only one worker performs the operation, ensuring correctness.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="handling-failures">Handling Failures<a href="https://clustron.io/blog/distributed-locks-explained/#handling-failures" class="hash-link" aria-label="Direct link to Handling Failures" title="Direct link to Handling Failures" translate="no">​</a></h2>
<p>Locks in Clustron are <strong>time‑bound</strong>.</p>
<p>When acquiring a lock, a duration must be specified:</p>
<div class="language-csharp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-csharp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> locks</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AcquireAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> TimeSpan</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromSeconds</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</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><br></span></code></pre></div></div>
<p>If the client holding the lock crashes or disconnects, the lock
eventually expires, allowing another worker to acquire it.</p>
<p>This prevents locks from remaining permanently held.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="best-practices">Best Practices<a href="https://clustron.io/blog/distributed-locks-explained/#best-practices" class="hash-link" aria-label="Direct link to Best Practices" title="Direct link to Best Practices" translate="no">​</a></h2>
<p>When implementing distributed locks:</p>
<ul>
<li class="">Keep critical sections short</li>
<li class="">Avoid global locks when possible</li>
<li class="">Partition locks by resource</li>
<li class="">Always design for failure scenarios</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="final-thoughts">Final Thoughts<a href="https://clustron.io/blog/distributed-locks-explained/#final-thoughts" class="hash-link" aria-label="Direct link to Final Thoughts" title="Direct link to Final Thoughts" translate="no">​</a></h2>
<p>Distributed locks are one of the most fundamental coordination
primitives in distributed systems.</p>
<p>They allow services running across multiple machines to safely
coordinate access to shared resources while preserving system
correctness.</p>
<p>Platforms like <strong>Clustron DKV</strong> simplify this by providing built‑in
locking primitives, atomic operations, and strong consistency
guarantees.</p>
<p>In the next article, we will explore another essential distributed
systems primitive:</p>
<p><strong>Leader Election.</strong></p>]]></content>
        <author>
            <name>Clustron Team</name>
            <uri>https://github.com/zeroheartbeat</uri>
        </author>
        <category label="Distributed Systems" term="Distributed Systems"/>
        <category label="distributed-locks" term="distributed-locks"/>
        <category label=".NET" term=".NET"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building Distributed Systems]]></title>
        <id>https://clustron.io/blog/building-distributed-systems/</id>
        <link href="https://clustron.io/blog/building-distributed-systems/"/>
        <updated>2026-03-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A Practical Guide for .NET Developers]]></summary>
        <content type="html"><![CDATA[<p><em>A Practical Guide for .NET Developers</em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://clustron.io/blog/building-distributed-systems/#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>Most backend systems begin their life on a single machine.</p>
<p>An ASP.NET Core application processes requests, a database stores application data, and background workers handle asynchronous tasks such as sending emails or generating reports. In this environment, concurrency is manageable and coordination between components is relatively straightforward.</p>
<p>As the system grows, however, things start to change.</p>
<p>Traffic increases, more application instances are deployed behind a load balancer, and services begin running across multiple machines. What was once a single application evolves into a distributed system.</p>
<p>At this point, the nature of the problem changes dramatically.</p>
<p>The challenges are no longer limited to writing correct business logic. Developers must now deal with coordination across machines, network failures, partial outages, and maintaining consistency across distributed state.</p>
<p>This is where distributed systems engineering begins.</p>
<hr>
<p><img decoding="async" loading="lazy" alt="Distributed Systems Architecture" src="https://clustron.io/assets/images/archtiecture-9fffb59f241d3092b4583974bc19d73b.png" width="1536" height="1024" class="img_ev3q"></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-a-distributed-system">What Is a Distributed System?<a href="https://clustron.io/blog/building-distributed-systems/#what-is-a-distributed-system" class="hash-link" aria-label="Direct link to What Is a Distributed System?" title="Direct link to What Is a Distributed System?" translate="no">​</a></h2>
<p>A distributed system is a collection of independent computers that appear to the user as a single coherent system.</p>
<p>Instead of running all logic on one machine, responsibilities are distributed across multiple nodes that communicate over the network.</p>
<p>Examples include:</p>
<ul>
<li class="">Microservice architectures</li>
<li class="">Distributed databases</li>
<li class="">Clustered caches</li>
<li class="">Message queues</li>
<li class="">Cloud infrastructure platforms</li>
</ul>
<p>These systems provide scalability and resilience but introduce new complexities.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-distributed-systems-are-hard">Why Distributed Systems Are Hard<a href="https://clustron.io/blog/building-distributed-systems/#why-distributed-systems-are-hard" class="hash-link" aria-label="Direct link to Why Distributed Systems Are Hard" title="Direct link to Why Distributed Systems Are Hard" translate="no">​</a></h2>
<p>Unlike a single-machine application, distributed systems must deal with realities such as:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="network-failures">Network Failures<a href="https://clustron.io/blog/building-distributed-systems/#network-failures" class="hash-link" aria-label="Direct link to Network Failures" title="Direct link to Network Failures" translate="no">​</a></h3>
<p>In distributed systems, communication happens over a network. Networks can be slow, unreliable, or temporarily unavailable.</p>
<p>A request may fail because the remote node crashed, because the network dropped packets, or because a timeout occurred.</p>
<p>The system must handle these scenarios gracefully.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="partial-failures">Partial Failures<a href="https://clustron.io/blog/building-distributed-systems/#partial-failures" class="hash-link" aria-label="Direct link to Partial Failures" title="Direct link to Partial Failures" translate="no">​</a></h3>
<p>In a distributed system, components can fail independently.</p>
<p>One node in a cluster might crash while others remain healthy. A service instance may restart while other services continue running.</p>
<p>This means the system must operate correctly even when only part of it is functioning.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="consistency-challenges">Consistency Challenges<a href="https://clustron.io/blog/building-distributed-systems/#consistency-challenges" class="hash-link" aria-label="Direct link to Consistency Challenges" title="Direct link to Consistency Challenges" translate="no">​</a></h3>
<p>When data is replicated across multiple nodes, keeping it consistent becomes difficult.</p>
<p>For example:</p>
<ul>
<li class="">Two nodes may attempt to update the same data simultaneously.</li>
<li class="">Network delays may cause nodes to temporarily disagree about the current state.</li>
<li class="">A node might crash after performing only part of an operation.</li>
</ul>
<p>Designing systems that maintain consistent state despite these scenarios requires careful coordination.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-building-blocks-of-distributed-systems">Key Building Blocks of Distributed Systems<a href="https://clustron.io/blog/building-distributed-systems/#key-building-blocks-of-distributed-systems" class="hash-link" aria-label="Direct link to Key Building Blocks of Distributed Systems" title="Direct link to Key Building Blocks of Distributed Systems" translate="no">​</a></h2>
<p>Most distributed systems rely on a few core primitives.</p>
<p>Understanding these primitives helps developers design reliable architectures.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="distributed-storage">Distributed Storage<a href="https://clustron.io/blog/building-distributed-systems/#distributed-storage" class="hash-link" aria-label="Direct link to Distributed Storage" title="Direct link to Distributed Storage" translate="no">​</a></h3>
<p>Data must often be stored across multiple machines.</p>
<p>This enables:</p>
<ul>
<li class="">horizontal scaling</li>
<li class="">fault tolerance</li>
<li class="">high availability</li>
</ul>
<p>Distributed key-value stores are commonly used for this purpose.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="coordination">Coordination<a href="https://clustron.io/blog/building-distributed-systems/#coordination" class="hash-link" aria-label="Direct link to Coordination" title="Direct link to Coordination" translate="no">​</a></h3>
<p>Nodes must coordinate actions such as:</p>
<ul>
<li class="">leader election</li>
<li class="">distributed locking</li>
<li class="">cluster membership</li>
<li class="">configuration updates</li>
</ul>
<p>Without coordination mechanisms, multiple nodes might attempt conflicting operations.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="consensus">Consensus<a href="https://clustron.io/blog/building-distributed-systems/#consensus" class="hash-link" aria-label="Direct link to Consensus" title="Direct link to Consensus" translate="no">​</a></h3>
<p>Some systems require strong guarantees about shared state.</p>
<p>Consensus algorithms such as <strong>Raft</strong> or <strong>Paxos</strong> allow nodes to agree on decisions even in the presence of failures.</p>
<p>These algorithms are fundamental to distributed databases and coordination services.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="partitioning-and-replication">Partitioning and Replication<a href="https://clustron.io/blog/building-distributed-systems/#partitioning-and-replication" class="hash-link" aria-label="Direct link to Partitioning and Replication" title="Direct link to Partitioning and Replication" translate="no">​</a></h3>
<p>Data is typically:</p>
<ul>
<li class=""><strong>partitioned</strong> across nodes to distribute load</li>
<li class=""><strong>replicated</strong> to protect against failures</li>
</ul>
<p>Balancing performance, availability, and consistency is one of the core design challenges.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-distributed-system-patterns">Common Distributed System Patterns<a href="https://clustron.io/blog/building-distributed-systems/#common-distributed-system-patterns" class="hash-link" aria-label="Direct link to Common Distributed System Patterns" title="Direct link to Common Distributed System Patterns" translate="no">​</a></h2>
<p>Several patterns appear repeatedly in real-world systems.</p>
<p>Examples include:</p>
<ul>
<li class="">Leader election for coordinating cluster activities</li>
<li class="">Distributed locks for ensuring mutual exclusion</li>
<li class="">Job queues for asynchronous processing</li>
<li class="">Rate limiters for controlling request volume</li>
<li class="">Transaction protocols for atomic multi-node updates</li>
</ul>
<p>These patterns form the foundation of many large-scale platforms.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-role-of-coordination-systems">The Role of Coordination Systems<a href="https://clustron.io/blog/building-distributed-systems/#the-role-of-coordination-systems" class="hash-link" aria-label="Direct link to The Role of Coordination Systems" title="Direct link to The Role of Coordination Systems" translate="no">​</a></h2>
<p>To simplify distributed development, many organizations rely on coordination systems such as:</p>
<ul>
<li class="">etcd</li>
<li class="">ZooKeeper</li>
<li class="">Consul</li>
</ul>
<p>These systems provide primitives such as:</p>
<ul>
<li class="">leader election</li>
<li class="">distributed locks</li>
<li class="">cluster membership</li>
<li class="">configuration storage</li>
</ul>
<p>Applications can then build higher-level behavior on top of these primitives.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="distributed-systems-in-the-net-ecosystem">Distributed Systems in the .NET Ecosystem<a href="https://clustron.io/blog/building-distributed-systems/#distributed-systems-in-the-net-ecosystem" class="hash-link" aria-label="Direct link to Distributed Systems in the .NET Ecosystem" title="Direct link to Distributed Systems in the .NET Ecosystem" translate="no">​</a></h2>
<p>While distributed infrastructure tools are often associated with other ecosystems, .NET applications increasingly operate in distributed environments.</p>
<p>Modern .NET systems frequently use:</p>
<ul>
<li class="">Kubernetes</li>
<li class="">distributed caches</li>
<li class="">microservices</li>
<li class="">event-driven architectures</li>
</ul>
<p>As a result, coordination and distributed state management are becoming increasingly important for .NET developers as well.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="final-thoughts">Final Thoughts<a href="https://clustron.io/blog/building-distributed-systems/#final-thoughts" class="hash-link" aria-label="Direct link to Final Thoughts" title="Direct link to Final Thoughts" translate="no">​</a></h2>
<p>Building distributed systems is fundamentally different from building traditional single-machine applications.</p>
<p>The challenges of network communication, partial failures, and data consistency introduce complexities that require specialized patterns and infrastructure.</p>
<p>Fortunately, by understanding the key building blocks — storage, coordination, consensus, and replication — developers can design systems that scale reliably and remain resilient in the face of failures.</p>
<p>In future articles, we will explore some of these primitives in more detail, including leader election, distributed coordination patterns, and practical implementations in .NET.</p>]]></content>
        <author>
            <name>Clustron Team</name>
            <uri>https://github.com/zeroheartbeat</uri>
        </author>
        <category label="Distributed Systems" term="Distributed Systems"/>
        <category label=".NET" term=".NET"/>
        <category label="Architecture" term="Architecture"/>
    </entry>
</feed>