<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>State and Concurrency on FsFlow</title>
    <link>https://adz.github.io/FsFlow/docs/state-concurrency/</link>
    <description>Recent content in State and Concurrency on FsFlow</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="https://adz.github.io/FsFlow/docs/state-concurrency/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Ref (Atomic References)</title>
      <link>https://adz.github.io/FsFlow/docs/state-concurrency/ref/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://adz.github.io/FsFlow/docs/state-concurrency/ref/</guid>
      <description>&lt;h1 id=&#34;ref-atomic-references&#34;&gt;Ref (Atomic References)&lt;/h1&gt;&#xA;&lt;p&gt;&lt;code&gt;Ref&amp;lt;&#39;T&amp;gt;&lt;/code&gt; is a handle to a mutable reference that can be updated atomically. It is the simplest way to manage shared state between multiple concurrent parts of your application.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;Ref&lt;/code&gt; is currently available on &lt;strong&gt;.NET&lt;/strong&gt; only.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;why-use-ref&#34;&gt;Why Use Ref?&lt;/h2&gt;&#xA;&lt;p&gt;In a functional program, state is usually passed as parameters or through the environment. However, some scenarios—like a shared counter, a cache, or a status flag—require multiple concurrent workflows to observe and update the same value.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Schedule (Retry &amp; Repeat)</title>
      <link>https://adz.github.io/FsFlow/docs/state-concurrency/schedule/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://adz.github.io/FsFlow/docs/state-concurrency/schedule/</guid>
      <description>&lt;h1 id=&#34;schedule-retry--repeat&#34;&gt;Schedule (Retry &amp;amp; Repeat)&lt;/h1&gt;&#xA;&lt;p&gt;The &lt;code&gt;Schedule&lt;/code&gt; module provides a powerful DSL for describing policies that govern how and when a workflow should be executed again. You can use schedules to implement sophisticated retry strategies (like exponential backoff with jitter) or recurring tasks.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;Schedule&lt;/code&gt; is currently available on &lt;strong&gt;.NET&lt;/strong&gt; only.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;basic-schedules&#34;&gt;Basic Schedules&lt;/h2&gt;&#xA;&lt;p&gt;A schedule decides two things:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Whether to continue (recur).&lt;/li&gt;&#xA;&lt;li&gt;How long to wait before the next attempt.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;fixed-number-of-recursions&#34;&gt;Fixed Number of Recursions&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fsharp&#34; data-lang=&#34;fsharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Recur 5 times (6 attempts total)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;fiveTimes&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schedule&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;recurs&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;fixed-spacing&#34;&gt;Fixed Spacing&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fsharp&#34; data-lang=&#34;fsharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Recur indefinitely with 1 second between attempts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;everySecond&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schedule&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;spaced&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;TimeSpan&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;FromSeconds&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;exponential-backoff&#34;&gt;Exponential Backoff&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fsharp&#34; data-lang=&#34;fsharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Delays: 100ms, 200ms, 400ms, 800ms...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;backoff&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schedule&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;exponential&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;TimeSpan&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;FromMilliseconds&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;adding-jitter&#34;&gt;Adding Jitter&lt;/h3&gt;&#xA;&lt;p&gt;Jitter adds randomness to delays to prevent &amp;ldquo;thundering herd&amp;rdquo; problems in distributed systems. &lt;code&gt;Schedule.jittered&lt;/code&gt; adds a random factor between 0.5x and 1.5x to the current delay.&lt;/p&gt;</description>
    </item>
    <item>
      <title>STM (Software Transactional Memory)</title>
      <link>https://adz.github.io/FsFlow/docs/state-concurrency/stm/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://adz.github.io/FsFlow/docs/state-concurrency/stm/</guid>
      <description>&lt;h1 id=&#34;stm-software-transactional-memory&#34;&gt;STM (Software Transactional Memory)&lt;/h1&gt;&#xA;&lt;p&gt;Software Transactional Memory (STM) is a powerful concurrency primitive that allows you to combine multiple atomic operations into a single &lt;strong&gt;transaction&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;While &lt;code&gt;Ref&lt;/code&gt; is perfect for updating a single variable, &lt;code&gt;STM&lt;/code&gt; is designed for scenarios where you need to update &lt;strong&gt;multiple&lt;/strong&gt; variables consistently. FsFlow ensures that the entire transaction is executed atomically—either all changes are committed, or none are.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;STM&lt;/code&gt; is currently available on &lt;strong&gt;.NET&lt;/strong&gt; only.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stream (FlowStream)</title>
      <link>https://adz.github.io/FsFlow/docs/state-concurrency/stream/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://adz.github.io/FsFlow/docs/state-concurrency/stream/</guid>
      <description>&lt;h1 id=&#34;stream-flowstream&#34;&gt;Stream (FlowStream)&lt;/h1&gt;&#xA;&lt;p&gt;&lt;code&gt;FlowStream&amp;lt;&#39;env, &#39;error, &#39;value&amp;gt;&lt;/code&gt; represents a &lt;strong&gt;cold&lt;/strong&gt;, pull-based asynchronous stream. Like &lt;code&gt;Flow&lt;/code&gt;, a &lt;code&gt;FlowStream&lt;/code&gt; requires an environment to run and can fail with a typed error. It is built on top of .NET&amp;rsquo;s &lt;code&gt;IAsyncEnumerable&lt;/code&gt;, providing native support for backpressure and asynchronous iteration.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;FlowStream&lt;/code&gt; is currently available on &lt;strong&gt;.NET&lt;/strong&gt; only.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;creating-a-stream&#34;&gt;Creating a Stream&lt;/h2&gt;&#xA;&lt;h3 id=&#34;from-a-sequence&#34;&gt;From a Sequence&lt;/h3&gt;&#xA;&lt;p&gt;The simplest way to create a stream is from an existing &lt;code&gt;seq&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fsharp&#34; data-lang=&#34;fsharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;numbers&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;FlowStream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;fromSeq&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;..&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;10&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;transforming-streams&#34;&gt;Transforming Streams&lt;/h2&gt;&#xA;&lt;h3 id=&#34;mapping-values&#34;&gt;Mapping Values&lt;/h3&gt;&#xA;&lt;p&gt;You can transform the successful values in a stream using &lt;code&gt;FlowStream.map&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
