﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>reaqtive.net</title>
    <link>https://reaqtive.net/feed/rss.xml</link>
    <description>Reaqtor is a framework for reliable, stateful, distributed, and scalable event processing based on Rx.</description>
    <copyright>Endjin Limited 2024</copyright>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>Argotic Syndication Framework 3000.0.5.0, http://www.codeplex.com/Argotic</generator>
    <language>en-GB</language>
    <lastBuildDate>Thu, 23 Sep 2021 00:00:00 GMT</lastBuildDate>
    <item>
      <title>On .NET Live - Scalable event processing with Reaqtor</title>
      <description>&lt;p&gt;In this live session Cecil Phillip was joined by Principal Software Engineer Bart De Smet to learn about the Reaqtor project.&lt;/p&gt;
&lt;p&gt;Reaqtor is a framework for creating reliable, stateful, distributed, and scalable event processing based on Reactive Extensions.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/on-dotnet-live-scalable-event-processing-with-reaqtor.html</link>
      <author>Bart De Smet</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/on-dotnet-live-scalable-event-processing-with-reaqtor.html</guid>
      <pubDate>Thu, 23 Sep 2021 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>In this live session Cecil Phillip was joined by Principal Software Engineer Bart De Smet to learn about the Reaqtor project.</p>
<p>Reaqtor is a framework for creating reliable, stateful, distributed, and scalable event processing based on Reactive Extensions.</p>
<p><a href="https://www.youtube.com/watch?v=7Onm8vo8bdg"><img src="/assets/images/talks/on-dotnet-live-scalable-event-processing-with-reaqtor.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Reaqtor - Reliable Rx at Scale for High-performance Event Processing</title>
      <description>&lt;p&gt;The Reactive Extensions for .NET (Rx) is one of the most influential technologies to have emerged from the .NET ecosystem. (Its influence on other platforms has been so pervasive that its origins in .NET are sometimes forgotten.)&lt;/p&gt;
&lt;p&gt;The team that created Rx did not rest on their laurels: they used Rx as the basis for developing a distributed, reliable, and extremely scalable event processing service. Reactor, as it was then called, has been integral to some of Microsoft's most widely used services for many years, including Cortana and Office 365, but although Microsoft has talked in public about it a few times, it has never been available for use outside of Microsoft—until now.&lt;/p&gt;
&lt;p&gt;On May 18th 2021, Bart de Smet, made Reaqtor (its new name) open source, as a .NET-Foundation-sponsored project.&lt;/p&gt;
&lt;p&gt;This talk will explain what makes Reaqtor different from other high-scale event processing systems. It will also show some of the foundational components that have been released as part of this, most notably 'Bonsai', a mechanism for serializing computations based on .NET's expression tree system, and which is central to how Reaqtor works.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/reaqtor-reliable-rx-at-scale-for-high-performance-event-processing.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/reaqtor-reliable-rx-at-scale-for-high-performance-event-processing.html</guid>
      <pubDate>Tue, 22 Jun 2021 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>The Reactive Extensions for .NET (Rx) is one of the most influential technologies to have emerged from the .NET ecosystem. (Its influence on other platforms has been so pervasive that its origins in .NET are sometimes forgotten.)</p>
<p>The team that created Rx did not rest on their laurels: they used Rx as the basis for developing a distributed, reliable, and extremely scalable event processing service. Reactor, as it was then called, has been integral to some of Microsoft's most widely used services for many years, including Cortana and Office 365, but although Microsoft has talked in public about it a few times, it has never been available for use outside of Microsoft—until now.</p>
<p>On May 18th 2021, Bart de Smet, made Reaqtor (its new name) open source, as a .NET-Foundation-sponsored project.</p>
<p>This talk will explain what makes Reaqtor different from other high-scale event processing systems. It will also show some of the foundational components that have been released as part of this, most notably 'Bonsai', a mechanism for serializing computations based on .NET's expression tree system, and which is central to how Reaqtor works.</p>
<p><a href="https://www.youtube.com/watch?v=K5A3uP75XNQ"><img src="/assets/images/talks/dotnet-oxford-2021-reaqtor-reliable-rx-at-scale-for-high-performance-event-processing.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>How Reaqtor combines reactivity with reliable data processing</title>
      <description>One of the big features that distinguishes Reaqtor from classic Rx is the ability to run long running stateful queries. It does this through the persistence of state which allows these queries to survive restarts, outages and even moving between different machines. It is the ability to execute these incredibly long running queries that enables support for services like Bing, Cortana and M365.</description>
      <link>https://reaqtive.net/blog/2021/05/how-reaqtor-combines-reactivity-with-reliable-data-processing.html</link>
      <author>Carmel Eve</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/how-reaqtor-combines-reactivity-with-reliable-data-processing.html</guid>
      <pubDate>Sat, 22 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>One of the big features that distinguishes Reaqtor from classic Rx is the ability to run long running stateful queries. It does this through the persistence of state which allows these queries to survive restarts, outages and even moving between different machines. The Reaqtor framework supports this by persistently storing the state via checkpointing.</p>
<h3 id="but-what-does-this-mean">But what does this mean?</h3>
<p>Let’s use the <code>Take</code> operator as an example.</p>
<p>Firstly, using normal Rx, let's say we used this operator to take the first 8 items in an observable stream as follows:</p>
<pre><code class="language-cs">var taken = observable.Take(8)
</code></pre>
<p>We will assume that the observable stream acts like a queue, where items are processed once and then removed from the queue.</p>
<p>Using the code above, we would only take the first 8 items in the stream. However, if the process was restarted then the <code>Take</code> operator would be reapplied and we would again take the first 8 items.</p>
<p>This would mean that all of the items that had previously been processed would be lost, and that the first 8 items from part way through the stream would be processed.</p>
<p>When using Reaqtor on the other hand, a key feature is that operator state is persistent.</p>
<h2 id="in-reaqtor">In Reaqtor</h2>
<p>The way this works is that the reactive engine generates checkpoints regularly. These checkpoints record where in the stream you have reached, and the operator state at that point.</p>
<p>This means that should the engine be restarted, you can restart processing from where you left off. Not only this, but the preserving of operator state means that operations (such as take) will not be reapplied.</p>
<p>Let's run through a demo to highlight what this looks like. The main method of the demo looks like this:</p>
<pre><code class="language-cs">static async Task Main(string[] args)
{
    await PayNoAttentionToTheManBehindTheCurtain();
    switch (args[0])
    {
        case &quot;1&quot;:
            await Part1();
            break;
        case &quot;2&quot;:
            await Part2();
            break;
    }
    ps.Dispose();
}
</code></pre>
<p>Where we can either run <code>Part1</code> or <code>Part2</code> each time we start up the process.</p>
<h3 id="part-1">Part 1</h3>
<p>When we start up Reaqtor's query engine we run the following code:</p>
<pre><code class="language-cs">Uri queryEngineIdentifier = new Uri(&quot;demo://test/engine1&quot;);

var engine = new QueryEngine(queryEngineIdentifier, scheduler, store, ingressEgressManager);

await engine.RecoverAsync(store.GetReader());

var ctx = new ReactorContext(engine);
</code></pre>
<p>First, we recover the query engine from any existing state (at this point no subscriptions have been started in the engine, so when it starts nothing will happen).</p>
<p>Once we have instantiated our query engine, we then get a reference to definitions of the <code>timer</code> observable , and the <code>consoleOutput</code> observer which will allow us to produce output to the console:</p>
<pre><code class="language-cs">var timer = ctx.GetObservable&lt;TimeSpan, DateTimeOffset&gt;(new Uri(&quot;demo://observables/timer&quot;));
var consoleOutput = ctx.GetObserver&lt;double&gt;(new Uri(&quot;demo://observers/cout&quot;));
</code></pre>
<p>We are able to retrieve these from there definitions becase they have been registered on the reactive context:</p>
<pre><code class="language-cs">await ctx.DefineObserverAsync(new Uri(&quot;demo://observers/cout&quot;), 
                              ctx.Provider.CreateQbserver&lt;T&gt;(Expression.New(typeof(ConsoleObserver&lt;T&gt;))), 
                              null, 
                              CancellationToken.None);

await ctx.DefineObservableAsync&lt;TimeSpan, DateTimeOffset&gt;(new Uri(&quot;demo://observables/timer&quot;), 
                                                          t =&gt; new TimerObservable(t).AsAsyncQbservable(), 
                                                          null, 
                                                          CancellationTokenNone);
</code></pre>
<p>In this case the observer/observable definitions are a part of the demo project, e.g.:</p>
<pre><code class="language-cs">internal sealed class ConsoleObserver&lt;T&gt; : IObserver&lt;T&gt;
{
    public void OnCompleted() =&gt; Console.WriteLine(&quot;OnCompleted()&quot;);
    public void OnError(Exception error) =&gt; Console.WriteLine($&quot;OnError({error})&quot;);
    public void OnNext(T value) =&gt; Console.WriteLine($&quot;OnNext({value})&quot;);
}
</code></pre>
<p>However there are many of these types defined as part of Reaqtor, with more being added as we speak!</p>
<p>Once we have retrieved our <code>timer</code> and <code>consoleOutput</code> definitions, we can then use them to create a subscription:</p>
<pre><code class="language-cs">var currentSpeedObservable =
    timer(TimeSpan.FromSeconds(1))
    .Select(_ =&gt; GetSpeed())
    .Take(8);
</code></pre>
<p>This takes the timer observable definition, tells it to call the <code>GetSpeed</code> method every second, and take the first 8 of those values. This is an asynchronous process definition, and no work will start until something subscribes.</p>
<p>The report speed method here is just reporting a random number:</p>
<pre><code class="language-cs">private static double GetSpeed()
{
    return Math.Round((30 + (new Random().NextDouble() * 5)), 0);
}
</code></pre>
<p>But this is where the real data that you are processing using Reaqtor would be produced. This data could be anything - current speed, temperature, failure events, location data, etc. Reaqtor has the potential to be used in a huge variety of different scenarios - many of which we are yet to think of!</p>
<p>So, we will now subscribe our <code>consoleOutput</code> observer:</p>
<pre><code class="language-cs">await currentSpeedObservable.SubscribeAsync(consoleOutput, 
                                            new Uri(&quot;demo://subscriptions/sub1&quot;), 
                                            null, 
                                            CancellationToken.None);
</code></pre>
<p>And wait 4 seconds before checkpointing and then unloading the engine:</p>
<pre><code class="language-cs">await Task.Delay(TimeSpan.FromSeconds(4.3));
await engine.CheckpointAsync(store.GetWriter());
await engine.UnloadAsync();
</code></pre>
<p>When we run the code, we will see the following output:</p>
<pre><code>OnNext(34)
OnNext(33)
OnNext(33)
OnNext(32)
OnNext(30)
Engine was unloaded, saving state...
State saved.
</code></pre>
<p>We can see that five items are passed to the <code>OnNext</code> method of our output observer. The engine is then unloaded and the state is saved.</p>
<p>Back in the code we can see that we are writing this state out to a file on disk:</p>
<pre><code class="language-cs">Console.WriteLine(&quot;Engine was unloaded, saving state...&quot;);

string json = store.AsJson();

File.WriteAllText(&quot;State.json&quot;, json);
Console.WriteLine(&quot;State saved.&quot;);
</code></pre>
<p>After saving out this state, we reach the end of the <code>Part1</code> method and the program exits.</p>
<h3 id="part-2">Part 2</h3>
<p>If we now restart the program, this time running <code>Part2</code>, we again start by reloading the engine from the stored state:</p>
<pre><code class="language-cs">string json = File.ReadAllText(&quot;State.json&quot;);
store = InMemoryKeyValueStore.FromJson(json);
var engine = new QueryEngine(QueryEngineIdentifier, scheduler, store, ingressEgressManager);
await engine.RecoverAsync(store.GetReader());
</code></pre>
<p>As soon as the engine recovers, it finds that there are unprocessed items which need to be passed to our <code>consoleOutput</code> observer, and the following output will be produced:</p>
<pre><code>Loading state...
Recovering from stored state
Recovery complete
OnNext(31)
OnNext(30)
OnNext(33)
</code></pre>
<p>We can see that the remaining items from the observable are now passed to our observer. Unlike in regular Rx, the state of the <code>Take</code> operator has been saved and instead of restarting and taking the next 8 items, it remembers that it has already taken 5 and just produces the remaining 3.</p>
<p>Therefore, processing continues as if the restart had never happened.</p>
<p>The fact that queries can continue to run throughout engine restarts means that you have the ability to support extremely long running operations. These queries can move between separate processes and machines, with the current state of the process being written out to persistent storage.</p>
<p>Reaqtor also gives assurances about reliability that mean that you can be sure that no state will be lost throughout these restarts, and that you can run Rx-like queries but with predictable and repeatable results.</p>
<p>The upshot is that you can create queries which can run for hours, days, months, or even years! Without worrying about engine restarts losing state, or producing unpredictable and incorrect results. And, it this ability to execute these incredibly long running queries that enables support for services like Bing, Cortana and M365.</p>
<p>This exciting technology brings the world of live, reactive, Rx-based queries together with the long-term persistence of information!</p>
<p>Here's <a href="https://reaqtive.net/talks/how-reaqtor-combines-reactivity-with-reliable-data-processing">a link to a video recording of this demo</a>.</p>
<p>And if you want to know more about Reaqtor, head over to <a href="https://reaqtive.net/">reaqtive.net</a> for more detail about how it works, the kind of scenarios it can support, and the history of the project!</p>]]></content:encoded>
    </item>
    <item>
      <title>Rx as a Service</title>
      <description>&lt;p&gt;This demo shows how Reaqtor enables us to use an Rx-like event processing model, but in a persistent, reliable, cloud-hosted environment.&lt;/p&gt;
&lt;p&gt;It shows a live stream of shipping location data (&lt;a href="https://github.com/ais-dotnet/"&gt;AIS&lt;/a&gt;) initially handled with classic Rx, and then shows how Reaqtor can host this same processing model as a long-running subscription in the cloud.&lt;/p&gt;
&lt;p&gt;See the talk &lt;a href="https://reaqtive.net/talks/durability-and-reliability-in-reaqtor-subscriptions.html"&gt;Durability and Reliability in Reaqtor Subscriptions&lt;/a&gt; for the second part of this demo.&lt;/p&gt;
&lt;p&gt;Note: this demo uses &lt;a href="https://reaqtor.cloud"&gt;reaqtor.cloud&lt;/a&gt;, endjin's  proprietary Azure Service Fabric based host for the Reaqtor primitives.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/rx-as-a-service.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/rx-as-a-service.html</guid>
      <pubDate>Thu, 20 May 2021 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>This demo shows how Reaqtor enables us to use an Rx-like event processing model, but in a persistent, reliable, cloud-hosted environment.</p>
<p>It shows a live stream of shipping location data (<a href="https://github.com/ais-dotnet/">AIS</a>) initially handled with classic Rx, and then shows how Reaqtor can host this same processing model as a long-running subscription in the cloud.</p>
<p>See the talk <a href="https://reaqtive.net/talks/durability-and-reliability-in-reaqtor-subscriptions.html">Durability and Reliability in Reaqtor Subscriptions</a> for the second part of this demo.</p>
<p>Note: this demo uses <a href="https://reaqtor.cloud">reaqtor.cloud</a>, endjin's  proprietary Azure Service Fabric based host for the Reaqtor primitives.</p>
<p><a href="530959928"><img src="/assets/images/talks/rx-as-a-service.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Durability and Reliability in Reaqtor Subscriptions</title>
      <description>&lt;p&gt;One of the most important features that Reaqtor adds to the Rx model is that the subscriptions it hosts are persistent.&lt;/p&gt;
&lt;p&gt;Just as when you store data in a database, you can rely on that data to survive across reboots and even hardware failures, the same is true of a Reaqtor subscription.&lt;/p&gt;
&lt;p&gt;See the talk &lt;a href="https://reaqtive.net/talks/rx-as-a-service.html"&gt;Rx as a Service&lt;/a&gt; for the first part of this demo.&lt;/p&gt;
&lt;p&gt;Note: this demo uses &lt;a href="https://reaqtor.cloud"&gt;reaqtor.cloud&lt;/a&gt;, endjin's  proprietary Azure Service Fabric based host for the Reaqtor primitives.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/durability-and-reliability-in-reaqtor-subscriptions.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/durability-and-reliability-in-reaqtor-subscriptions.html</guid>
      <pubDate>Wed, 19 May 2021 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>One of the most important features that Reaqtor adds to the Rx model is that the subscriptions it hosts are persistent.</p>
<p>Just as when you store data in a database, you can rely on that data to survive across reboots and even hardware failures, the same is true of a Reaqtor subscription.</p>
<p>See the talk <a href="https://reaqtive.net/talks/rx-as-a-service.html">Rx as a Service</a> for the first part of this demo.</p>
<p>Note: this demo uses <a href="https://reaqtor.cloud">reaqtor.cloud</a>, endjin's  proprietary Azure Service Fabric based host for the Reaqtor primitives.</p>
<p><a href="530378113"><img src="/assets/images/talks/durability-and-reliability-in-reaqtor-subscriptions.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Reaqtor's Open Source Journey</title>
      <description>Reaqtor is almost 10 years old. The journey to make it available as open source has taken over 5 years. Read how endjin spearheaded the process and became the project maintainers.</description>
      <link>https://reaqtive.net/blog/2021/05/reaqtors-open-source-journey.html</link>
      <author>Howard van Rooijen</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/reaqtors-open-source-journey.html</guid>
      <pubDate>Tue, 18 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Endjin's journey with Reaqtor started in 2016, with a hot cup of tea and a simple question:</p>
<blockquote>
<p>&quot;What single action could you take which would deliver the biggest positive impact on customer satisfaction?&quot;</p>
</blockquote>
<p>The question popped up in a Brain Trust session with <a href="https://www.linkedin.com/in/icorna/">Ilario Corna</a>, Head of Infrastructure, Content &amp; Operations at Talk Talk (a UK Telco). The organisation had just rolled out an objective to become the UK's &quot;most recommended provider&quot;. As part of this strategic initiative, we had designed and implemented an Azure based solution capable of ingesting and analysing over 200 million network telemetry events per day for anomalous behaviour.
Feeling buoyed by success we were wondering &quot;which hard problem could we tackle next?&quot;</p>
<p>Ilario had the answer immediately. &quot;Oh, that's easy&quot; he said, &quot;I would send a field engineer out to each customer's house, run diagnostics on their broadband connection and hardware, upgrade their firmware and implement any other tweaks required. But with over 1 million customers that's not commercially feasible to implement.&quot;</p>
<p>After taking a sip of tea and pondering for a few moments I responded &quot;So we have a solution, but we need to find a way to implement and scale it several orders of magnitude more cheaply. If I were in your shoes and could wave a magic wand, I'd want to be able to say something like 'Cortana, monitor the Quality of Service for each of my customer's connections, and if it's below our SLA, then run a trouble-shooter to diagnose why and then apply a number of automatic remediation strategies'. Wouldn't that be a great way to manage the network?&quot;</p>
<p>He responded with a chuckle, &quot;Sure would! When can I have it?!?&quot; We both laughed then, because it sounded like a far-off sci-fi fantasy.</p>
<p>On the train home, that part of the conversation kept coming back to me. Why couldn't we create some type of digital agent that could monitor not only the customer's device, but every part of the network infrastructure that led to the customers home? The nuance was that unlike traditional &quot;big data&quot; problems, whereby you need to reduce vast amounts of data into a format a human can comprehend, this type of problem is more akin to signals analysis: you need to process the full fidelity raw data in a stateful way.</p>
<p>If you have 1 million customers, you need demultiplex those 200 million messages into 1 million queries, each query will need to look at the message and ask &quot;does this apply to me?&quot; if so it would process the event and update its quality of service metric, evaluate if that had met a threshold and if so, trigger a new &quot;threshold exceeded&quot; event. Articulating the problem this way sounded a bit like the <a href="https://en.wikipedia.org/wiki/Actor_model">Actor Model</a>, or perhaps an Rx query.</p>
<p>A few years previously we had worked on an <a href="https://endjin.com/what-we-do/software-engineering">DevOps project</a> for a major UK online retailer. We used <a href="https://endjin.com/blog/2014/04/getting-started-with-semantic-logging">Rx to aggregate and disaggregate semantic logging events</a> from all the servers in the data centre. The Rx query we <a href="https://endjin.com/blog/2014/04/event-stream-manipulation-using-rx-part-1">implemented was simple</a>, elegant, and <a href="https://endjin.com/blog/2014/05/event-stream-manipulation-using-rx-part-2">incredibly powerful</a>; a testament to the design of Rx, and a reason we're huge fans of it at endjin.</p>
<p>I wondered if it would be possible to run 1 million Rx queries concurrently, and remembered <a href="https://reaqtive.net/talks/cloud-scale-event-processing-with-the-reactive-extensions.html">Bart De Smet has presented a session at NDC 2015 about Cloud Event Processing</a> the previous year, so I found &amp; watched the recording. In that talk he mentioned that he was working in the Bing organisation on an evolution of Rx which powered Cortana experiences, and this involved stateful, durable, high density Rx queries. This sounded very promising indeed!</p>
<p>While researching to see if this technology had been open sourced, I came across a Microsoft case study about &quot;Bing Cortana&quot; (unfortunately no longer public) that mentioned a technology called Reactor, which was used to evaluate 500 million queries per second. If this was the same technology, we only needed 1/500th of that capacity in order to solve our broadband Quality-of-Service monitoring scenario.</p>
<p>I reached out to <a href="https://www.linkedin.com/in/david-goon-82186830/">David Goon</a>, who was our Partner Manager at Microsoft, explained the situation and asked &quot;do you think it would within the realms of possibility for us to get access to this technology?&quot; He responded &quot;It's a really compelling use case, and I can see there being lots more across other sectors. Let me reach out to Bart De Smet and see what he says. We can only try.&quot; Within a couple of weeks, we had an hour long call with Bart where we took him through the scenario we had elaborated, and asked if he thought Reactor would be a viable solution. He said that it seemed to be a good fit, and we agreed to start collaborating on a proof of concept.</p>
<p>It's hard to convey what an absolute honour and privilege it has been to work with Bart, and I will be forever grateful for the amount of his incredibly valuable time he dedicated to this endeavour. It goes without saying that without him, absolutely none of what follows would have been possible. Reaqtor is Bart's baby; we've just had the privilege of delivering it into the world.</p>
<p>Once Bart provided us with access to some sample Reactor code, <a href="https://endjin.com/who-we-are/our-people/mike-larah/">Mike Larah</a> and I paired on a &quot;simple scenario&quot;; an entirely in-memory version of Reactor hosted in a Console App, based on the NDC talk code sample Bart shared with us. We wanted to see if we could solve the broadband anomaly detection problem by processing a stream of <a href="https://en.wikipedia.org/wiki/RADIUS">RADIUS</a> network telemetry and detecting the specific events that indicate there were problems in the broadband network. In this prototype we modelled the network as a graph, which allowed us to determine if an issue was localised to the customer's home or was occurring at a local (an outage for a street) or regional node level (an outage for a town). It worked, and we were fizzing with excitement.</p>
<p>One of the key points you need to understand is that Reactor is orders of magnitude bigger than <a href="https://github.com/dotnet/reactive">Reactive Extensions</a> with over 166 projects, and <a href="https://reaqtive.net/download/">90 NuGet packages</a>, and yet it is still a framework, not a platform. While state, durability and reliability are defined in the design of the framework, the implementation is missing, as this is tied to the hosting environment.</p>
<p>Reactor was born into Bing and adopted by M365 and other product teams. Bart had done a fantastic job of ensuring a clean separation of Reactor from the hosting environment, but it meant that we had to tackle the thorny problem of building our own reliable hosting platform, state store, ingress &amp; egress adapters, management &amp; control plane, and workbench for talking to Reactor. We had a mountain to climb.</p>
<p>When it comes to solving hard problems, <a href="https://reaqtive.net/team/ian-griffiths/">Ian Griffiths</a> has always been our first port of call; he's been an endjin associate since we founded the company. I knew he was very passionate about Rx as he'd included a chapter about the subject in his <a href="https://endjin.com/news/programming-csharp-8-is-available">Programming C#</a> series of books for O'Reilly, and we'd had many conversations about it. Over a few months we implemented an initial spike of a reliable hosting platform, and had an absolute blast while doing it. Shortly afterwards Ian joined endjin full time as <a href="https://endjin.com/blog/2018/12/a-conversation-with-ian-griffiths">our first Technical Fellow</a>, so that he could continue to work on the endeavour.</p>
<p>Over the next few years, we built several technical spikes exploring different facets of the Reactor technology; we embedded <a href="https://dotnet.microsoft.com/apps/machinelearning-ai/ml-dotnet">ML.NET models</a> into Reaqtor queries, we created a proof-of-concept anomaly detection temporal query (using virtual time) that could correctly identify broadband quality of service events that indicate outages; processing a days' worth of telemetry (around 40GB) in under 90 seconds. The ability to do &quot;what-if&quot; simulations over historic datasets, which we could then flip a switch and turn into live queries running against realtime data blew us away. I want to express my thanks to <a href="https://www.linkedin.com/in/ben-dyer-5aa7414/">Ben Dyer</a> and <a href="https://www.linkedin.com/in/alexkeysmith/">Alex KeySmith</a> for providing us with the anonymised dataset for this proof of concept - they were early believers.</p>
<p>In May 2018 <a href="https://endjin.com/who-we-are/our-people/matthew-adams/">Matthew Adams</a>, my co-founder at endjin, &amp; I flew over to Seattle for the Microsoft Build conference and we managed to spend our last day of the trip with Bart. In the morning Bart told us the story of how Reactor came to be (this is covered in detail in the &quot;<a href="https://reaqtive.net/#a-little-history-of-reaqtor">A Little History of Reaqtor</a>&quot; ebook you can download for free on the homepage). Over a fantastic lunch we waxed lyrical about the future of data processing, and Bart talked about his vision for <code>IComputationProcessing</code> (more about this in the ebook!) and then in the afternoon we talked about whether we could open source Reactor and what that process would entail.</p>
<p><a href="https://endjin.com/who-we-are/our-people/carmel-eve/">Carmel Eve</a>, who had interned with us the previous year, re-joined endjin on our <a href="https://endjin.com/who-we-are/join-us">Apprenticeship Programme</a>. Ian and Carmel started exploring Reactor with other proof of concepts covering different customer scenarios we had identified. Throughout this time Carmel documented her learnings <a href="https://endjin.com/blog/2018/11/understanding-rx-making-interfaces-subscribing-and-other-subjects-click">about Rx</a> and writing <a href="https://endjin.com/blog/2018/06/garbage-collection-a-memorandum-on-memory-in-csharp">high performance C#</a> in popular blog post series. The more we investigated Reactor, the more impressed we became.</p>
<p>In March 2019 I attended the MVP Summit in Redmond, and I bumped into <a href="https://twitter.com/jongalloway">Jon Galloway</a>, who at the time was the Executive Director of the .NET Foundation. I gave him as brief a Reactor elevator pitch as I could, and said that endjin would love to become <a href="https://dotnetfoundation.org/#corporate-sponsors">.NET Foundation Corporate Sponsors</a>, as we wanted to demonstrate our commitment to the .NET ecosystem, while we also collaborated with Bart to create whitepapers and a business case in order to justify the investment from Microsoft to carry out the legal processes required to open source Reactor to the .NET Foundation under <a href="https://github.com/reaqtive/reaqtor/blob/main/LICENSE">The MIT License</a>.</p>
<p>By the end of the year we'd filled out the paperwork, paid our sponsorship fee, and were featured on the .NET Foundation homepage alongside: AWS, DevExpress, Microsoft, Octopus Deploy, Telerik, Uno Platform and VMWare.</p>
<p>At this point, we had to face the problem that we had been avoiding for the past 3 years; what do we call it? &quot;Reactor&quot; as a name is too overused. <a href="https://developer.microsoft.com/en-us/reactor/">Microsoft Reactor</a> is the name of the Microsoft Community meet up venues around the world. <a href="https://projectreactor.io/">Project Reactor</a> is the name of a JVM project from VMWare, inspired by Rx, and based on Reactive Streams. <a href="https://reactjs.org/">React</a> is the hugely popular reactive user interface library from Facebook. One of the key concepts that powers Reactor is <code>IQbservable</code>. We've always loved this weirdly named interface (partly due to how Bart pronounces it - <code>I-Cub-servable</code>). Carmel came up with the suggestion that we include the &quot;Q&quot; in the name and as soon as Reaqtor was written down, it received unanimous agreement.</p>
<p>This also neatly solved two other naming problems we faced. Reaqtor consists of three conceptual layers; at the bottom a set of reusable components (that can be used independently of Reaqtor) which provide compiler, JSON and LINQ, and high performance / low memory extensions and utilities, which we named <a href="https://reaqtive.net/documentation/nuqleon/">Nuqleon</a>. The middle layer contains reactive primitives that evolve many of the concepts found in Rx to enable reliable, stateful and distributed reactive processing, which we named <a href="https://reaqtive.net/documentation/reaqtive/">Reaqtive</a>. And finally the top level consists of platform level services for building reliable, stateful, distributed reactive solutions, called <a href="https://reaqtive.net/documentation/reaqtor/">Reaqtor</a>.</p>
<p>We started to collaborate with the .NET Foundation to <a href="https://dotnetfoundation.org/projects/submit">onboard the project</a>. Special thanks to <a href="https://twitter.com/clairernovotny">Claire Novotny</a> who helped us set up the DevOps processes on the .NET Foundation infrastructure and all the other bits of administrivia required to prepare the project to be released to the public.</p>
<p>We also worked with <a href="https://twitter.com/rlittlesii">Rodney Littles</a> and the <a href="https://dotnetfoundation.org/about/technical-steering-group">.NET Technical Steering Group</a> to elaborate an RFC to modernise the Expression Tree subsystem, as it has not been invested in for many years and does not have parity with the latest language features. These improvements are fundamental to the future of Reaqtor. Fortunately there seems to be some <a href="https://github.com/dotnet/csharplang/discussions/4727">progress in this area</a> as the Entity Framework team would also like this modernisation to occur.</p>
<p>Part of the problem with Expression Trees is that they are one of the most complex and least well documented parts of .NET; they are also perceived only to exist to power LINQ (and LINQ Providers). As you'll see with Reaqtor (an in particular the Nuqleon layer, which is where the Expression Tree &amp; Bonsai subsystem lives), Expression Trees really are one of .NET super powers and enable mind-bending meta-programming scenarios.</p>
<p>One of the final puzzle pieces was how we could create a great documentation experience for the community. Ian has a long history in teaching programming; DevelopMentor, Pluralsight and his O'Reilly books. We've had many conversations about what a good learning environment looks like: the ability to tell a cohesive narrative including text, images, videos and code samples that you can execute in context (to eliminate task switching). <a href="https://docs.microsoft.com/">Microsoft Docs</a> have done an excellent job in this respect, but how can you offer a similar experience when you are a small open source project?</p>
<p>We initially investigated <a href="https://dotnet.microsoft.com/platform/try-dotnet">Try .NET</a> which lead us to talking to <a href="https://twitter.com/jonsequitur">Jon Sequeira</a>, <a href="https://twitter.com/colombod">Dr Diego Colombo</a>, <a href="https://twitter.com/LadyNaggaga">Maria Naggaga</a> and <a href="https://twitter.com/bvfors">Brett Forsgren</a>. Initial conversations quickly turned to their current project <a href="https://github.com/dotnet/interactive">.NET Interactive</a>, which seemed perfect for our needs, not only for interactive documentation but also as an IDE for writing, testing and running Reaqtor queries.</p>
<p>We soon realised that .NET Interactive was designed around a request/response (REPL) model, but we'd really need to support long running in-process and out of process reactive queries. We collaborated with the team on a design for a client-side command pattern that would allow us to define custom commands and send them between the kernels. Ian implemented the feature and the <a href="https://github.com/dotnet/interactive/pull/977">PR was merged into the .NET Interactive codebase</a>, allowing us to create great documentation and interesting demos, that you can use to understand Reaqtor, Reaqtive &amp; Nuqleon.</p>
<p>The final significant contributor to the project is <a href="https://blackspike.com/">Felix Corke</a> who designed the <a href="https://github.com/reaqtive/reaqtive-creative-assets">branding and creative assets</a> which we have made available under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution Share Alike 4.0 International</a> license, so that the community can use them in blog posts, videos and presentations about Reaqtor. We have also created a <a href="https://github.com/reaqtive/community-presentations">Community Presentations repository</a> containing branded, pre-canned presentations and demos using the existing interactive notebooks, so that you can easily do a presentation or lightning talk at your local .NET User Group.</p>
<p>Our journey with Reaqtor only covers a short period in its overall history. In his (free) ebook, <a href="https://reaqtive.net/#a-little-history-of-reaqtor">A Little History of Reaqtor</a> Bart De Smet tells the full story... starting in 2005. It is an absolutely fascinating account, and I hope by the time you finish reading it, you'll understand why we believe Reaqtor is the most exciting technology in the .NET ecosystem, that it's a game changer, and why we're so excited that you can <a href="https://github.com/reaqtive/reaqtor">get your hands on the framework</a>, <a href="https://reaqtive.net/demos/">run the demos</a>, read through the <a href="https://reaqtive.net/documentation/">conceptual</a> and <a href="https://reaqtive.net/documentation/api/">API</a> documentation, watch our growing collection of <a href="https://reaqtive.net/talks/">talks</a>, read our <a href="https://reaqtive.net/blog">blog</a> (and don't forget to subscribe to our <a href="https://reaqtive.net/rss.xml">RSS feed</a>) or chat to us <a href="https://reaqtive.net/slack">via Slack</a>. Please ⭐the <a href="https://reaqtive.net/github">GitHub Repos</a>, as we'd love to gauge community interest in the project.</p>
<p>There's currently a significant feature gap between the Reaqtor components that have been open sourced and what's required to implement a large scale production Reaqtor platform. That's why we've spent 5 years building <a href="https://reaqtor.cloud">reaqtor.cloud</a> a full, commercial cloud-native platform implementation of Reaqtor. We hope you'll join the <a href="https://reaqtor.cloud">waiting list</a> for the upcoming private preview.</p>]]></content:encoded>
    </item>
    <item>
      <title>How Reaqtor combines reactivity with reliable data processing</title>
      <description>&lt;p&gt;Reaqtor is an evolution of Rx and is used to power services in Bing, Cortana &amp;amp; M365. In order to support the long-running nature of some of the queries involved in these processes, it must be able to survive process restarts and even total migrations. It does this by persisting the current state of the system via &amp;quot;checkpointing&amp;quot;, enabling queries that can run for days, weeks, months, or even years!&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/how-reaqtor-combines-reactivity-with-reliable-data-processing.html</link>
      <author>Carmel Eve</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/how-reaqtor-combines-reactivity-with-reliable-data-processing.html</guid>
      <pubDate>Tue, 18 May 2021 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Reaqtor is an evolution of Rx and is used to power services in Bing, Cortana &amp; M365. In order to support the long-running nature of some of the queries involved in these processes, it must be able to survive process restarts and even total migrations. It does this by persisting the current state of the system via &quot;checkpointing&quot;, enabling queries that can run for days, weeks, months, or even years!</p>
<p><a href="552269133"><img src="/assets/images/talks/how-reaqtor-combines-reactivity-with-reliable-data-processing.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Sequences, LINQ, Rx, &amp; Reaqtor Part 6: Reaqtor</title>
      <description>In the final part in this series, we finally get to explore Reaqtor and understand how evolves the concepts of Rx for a cloud native world.</description>
      <link>https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-06-reaqtor.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-06-reaqtor.html</guid>
      <pubDate>Mon, 17 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>To understand Reaqtor, it is necessary to understand Rx (the Reactive Extensions for .NET). And to understand Rx, it is necessary to understand how C# works with sequences of items. In this series I have outlined the ideas at the heart of Reaqtor, and how they are handled in C#. In this final part, we see how all of the preceding articles in this series finally lead us to Reaqtor: a server technology that is able to host persistent Rx subscriptions, defined as LINQ queries.</p>
<p>As an example of what you might do with this, consider an application that wants to detect when a customer broadband router is experiencing a higher error rate than the average for the exchange to which the router is attached. A typical broadband provider will have millions of customers across hundreds of exchanges. These systems generate huge volumes of monitoring data, and it is necessary to identify and understand problems as they arise to pre-empt customer problems in order to reduce support costs and improve the customer's experience.</p>
<p>You could arrange for network health events be made available inside Reaqtor as event sources that can be subscribed to. You could then feed these events through the <code>GroupBy</code> operator to separate the data out by exchange, and then through a <code>Buffer</code> operator to calculate a rolling average error rate for each exchange as a whole. The results of this could then be made available within Reaqtor as an event source that other subscriptions can use.</p>
<p>You could then define subscriptions for each individual customer's router. (Remember, there will be millions of these routers, but Reaqtor is designed to handle that kind of scale easily.) Again we could use <code>Buffer</code> to calculate a rolling error rate, and then feed these through a <code>Where</code> clause that compares the router-specific error rate with the average for that router's exchange, only allowing through events that are above the average.</p>
<p>This way, you can get notifications from individual devices if they start to experience high failure rates while avoiding getting swamped by such notifications if it turns out that a large number of devices attached to the same exchange are all reporting similar failures due to an exchange-level problem. By combining a highly localized point of view (events from an individual router in a particular customer's house) with broader context (aggregated performance at the level of a whole telephone exchange) you can better understand the information you're seeing, e.g., you can distinguish between problems with individual pieces of equipment and broader failures.</p>
<p>This sort of logic can be expressed as LINQ queries using standard operators. These queries then get transferred into the 'Query Engine' inside Reaqtor (possibly via a 'Query Coordinator', which can optimize queries, and work out how to distribute them across multiple Query Engines to improve scale).</p>
<p>These then become long running queries which (unlike with ordinary Rx subscriptions) can continue to run long after the code that initially set them up has stopped running. Reaqtor has failover support enabling queries to migrate to new servers if the server they are running on needs to reboot, or just fails.</p>
<p>The basic abstraction underpinning this is the same one we saw in <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-01-sequences-and-ienumerable-of-t.html">the first article in this series</a>—a sequence of items. Processing and combination is enabled by the <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-02-linq.html">LINQ features</a>. We're able to do this reactively—in response to live events as they happen—thanks to <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-03-rx.html">Rx</a>, which has been augmented by <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-04-reaqtive.html">Reaqtive</a> to add with the additional concepts required for persistent, long-running subscriptions. <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-05-remotable-expressions.html">Remotable expression trees</a> enable both the remote instantiation of such subscriptions, but also their persistence. And Reaqtor then provides the runtime services required to make all of that real, offering a host environment for Rx-like subscriptions, with persistence, checkpointing, and failover, and it has a proven track record of scaling to tens of millions of customers.</p>]]></content:encoded>
    </item>
    <item>
      <title>Sequences, LINQ, Rx, &amp; Reaqtor Part 5: Remotable Expressions</title>
      <description>In the fifth part in this series we explore the ability to serialize expression trees and then remote them.</description>
      <link>https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-05-remotable-expressions.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-05-remotable-expressions.html</guid>
      <pubDate>Sun, 16 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>To understand Reaqtor, it is necessary to understand Rx (the Reactive Extensions for .NET). And to understand Rx, it is necessary to understand how C# works with sequences of items. In this series I am outlining the ideas at the heart of Reaqtor, and how they are handled in C#. In the preceding part, we saw how <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-04-reaqtive.html">Reaqtive</a> adds extra 'dimensions' to <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-03-rx.html">Rx</a>. In the final part we'll see how this comes into play in fully-fledge Reaqtor as a Service, but first, we need to look at one of the most distinctive aspects of the Reaqtive world.</p>
<p>One of the most important features added by Reaqtor, and its supporting libraries Nuqleon and Reaqtive, is the ability to serialize expression trees. We've already seen how with <code>IQueryable&lt;T&gt;</code>, it's possible to translate a LINQ query into something like SQL and execute it remotely. But with the ability to serialize expression trees, it becomes possible to enable remote execution of queries without needing to translate them to anything else: you can just ship an entire LINQ query to another process and run it there.</p>
<p>That capability is at the heart of Reaqtor.</p>
<p>First, there's the obvious fact that if you can send expressions over a network, this opens the door to being able to offer &quot;Rx as a service&quot;. Whereas with classic Rx, everything is inherently in-process, remotable expressions provide a way to send a description of a subscription to an external process. Slightly more subtly, serializable expressions also help enable persistence—if you have a serialized description of a subscription, you can store that somewhere persistent, and then reload it into a new service instance if the one it was previously running in stops running for any reason. (In practice, persistent subcriptions require more than just the ability to serialize their defining expressions: many Rx operators maintain state, which must also be persisted, but the serialization of expressions is still a crucial element.)</p>
<p>It isn't strictly necessary to understand the exact details of how expressions are serialized—in fact the Reaqtor codebase offers a couple of different formats. Normally, a JSON-based format is used, but there is also code in there for serializing to a binary representation. The fundamental capabilities are more interesting than the exact format details. So it's worth knowing that serialized expression trees ('Bonsai trees', as they are typically known) are able to represent more or less any expression that a .NET expression tree can, but they are not necessarily tied to .NET.</p>
<p>It's important to understand that Bonsai trees are not compiled code—we are not shipping IL (.NET's equivalent to Java bytecode) over the wire. They are a description of the original structure of the expression. Also, they are typically self-contained: there is normally no need to distribute any particular extra compiled code to the receiving service to enable it to understand the tree. (Contrast this with some systems that enable remote invocation of user-defined functions implemented in Java: Spark supports user-defined functions, but to be able to run inside the processing nodes of a Spark cluster, the compiled version of a function needs to be accessible to those nodes. So you typically end up distributing <code>.jar</code> files across the cluster. This is unnecessary with Bonsai trees because they can be self-contained. After a service converts one back to a .NET expression tree (applying any necessary security checks, and whatever transformations it requires), it can compile it into runnable code at runtime.)</p>
<p>Bonsai does support embedding very .NET-specific information if you want to. (E.g., a Bonsai tree could indicate that an expression invokes the <code>Where</code> operator defined by the <code>Queryable</code> class in the <code>System.Linq</code> namespace in a specific version of the .NET <code>System.Linq</code> assembly). But it doesn't have to work this way.</p>
<p>When used with Reaqtor, Bonsai trees often replace such specific references with more abstract ones. It is common to rewrite expression trees so that particular methods defined by certain types are replaced with a placeholder identifying the relevant method by a URI. So although your code might refer to <code>Queryable.Where</code>, the Reaqtor client library would arragne for the Bonsai representation to replace this with an unbound parameter named, say, <code>rx://operators/filter</code>. This ability to substitute URI-based names for particular members of specific .NET types has the useful effect of decoupling Bonsai trees from any particular versions of library components, or from any particular version of .NET.</p>
<p>In fact, expression trees don't necessarily have to originate from .NET. In principle, any language can generate a Bonsai tree, although it's likely to be a lot more convenient if your language has support for something similar to .NET's <code>Expression&lt;T&gt;</code>, in which compilers can be induced to produce code that builds a description of an expression instead of simply compiling an expression into runnable code.</p>
<p>In the <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-06-reaqtor.html">next and final part of this series</a>, we'll see how the various Nuqleon, Reaqtive and .NET features described so far come together to provide a reliable, persistent high-performance, event-based service called Reaqtor.</p>]]></content:encoded>
    </item>
    <item>
      <title>Sequences, LINQ, Rx, &amp; Reaqtor Part 4: Reaqtive</title>
      <description>In the fourth part in this series we explore the Reaqtiveframework including IReactiveObservable&lt;T&gt; and IReactiveQbservable&lt;T&gt;.</description>
      <link>https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-04-reaqtive.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-04-reaqtive.html</guid>
      <pubDate>Sat, 15 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>To understand Reaqtor, it is necessary to understand Rx (the Reactive Extensions for .NET). And to understand Rx, it is necessary to understand how C# works with sequences of items. In this series I will outline the ideas at the heart of Reaqtor, and how they are handled in C#. Last time, we saw how <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-03-rx.htmld">Rx</a> defines a push-oriented alternative representation of the basic sequence abstraction more often represented by <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-01-sequences-and-ienumerable-of-t.html"><code>IEnumerable&lt;T&gt;</code></a>. Now we're going to see how Rx has evolved into Reaqtive, adding some new capabilities that open the door for Rx as a service.</p>
<p>Rx has been around for some time. Early versions were released directly by Microsoft. It was open sourced in 2012, and then moved under the .NET Foundation's control a couple of years later. After a few slightly moribund years, community activity started to increase in 2017, and it continues to be actively maintained. However, Rx also lived on in parallel inside Microsoft in a form that was not public for many years. Part of what Microsoft has made available in the Reaqtor libraries is in effect the new version of Rx, now in various namespaces under Nuqleon, Reaqtive &amp; Reaqtor.</p>
<p>We've already seen a couple of 'dimensions' with <code>IEnumerable&lt;T&gt;</code> and Rx. We can think of the expression tree/callback choice (to <code>Q</code> or not to <code>Q</code>) as one particular dimension, and you can choose to stand in either the callback side or the expression tree side. This is independent of the pull/push choice, which is another dimension. We can choose between two options in that dimension too, leading to four possibilities: <code>IEnumerable&lt;T&gt;</code> (pull, callbacks), <code>IQueryable&lt;T&gt;</code> (pull, expressions), <code>IObservable&lt;T&gt;</code> (push, callbacks) or <code>IQbservable&lt;T&gt;</code> (push, expressions).</p>
<p>Reaqtive adds various extra dimensions. One is the nature of subscriptions. With classic Rx, when you subscribe to an <code>IObservable&lt;T&gt;</code> (or <code>IQbservable&lt;T&gt;</code>) it returns an <code>IDisposable</code>, and you can unsubscribe (i.e., decide you no longer want to receive events—the logical equivalent of executing a <code>break</code> statement in a <code>foreach</code> over an <code>IEnumerable&lt;T&gt;</code>) by calling <code>Dispose</code>. But Reaqtive elevates subscriptions to a more sophisticated level, making them entities in their own right, with some capabilities for walking over the participants of a subscription (e.g., enabling all the operators in a subscription to share a context). This is reflected in the <code>ISubscribable&lt;T&gt;</code> and <code>IQubscribable&lt;T&gt;</code> interfaces. (It does not extend the pull world in this way, so there's no <code>IReactiveEnumerable&lt;T&gt;</code>, for example. Not every conceivable position across all the dimensions is populated.) Another dimension concerns whether entities such as observable sources or subscriptions are identified purely by .NET object identity, or whether they have associated URIs acting as persistent names. In the latter case we have various interfaces with <code>Reactive</code> in their names such as <code>IReactiveObservable&lt;T&gt;</code> and <code>IReactiveQbservable&lt;T&gt;</code>. (Again, not every possible combination exists; these <code>Reactive</code> forms all have the same strong subscription model as <code>ISubscribable&lt;T&gt;</code>, and there's no <code>Reactive</code> flavour without that feature.)</p>
<p>Yet another dimension is async. Reaqtive defines <code>IAsyncReactiveObservable&lt;T&gt;</code> and <code>IAsyncReactiveQbservable&lt;T&gt;</code>. (Once more, not every conceivable corner of this hyperspace is populated: there is no <code>IAsyncObservable&lt;T&gt;</code> for example. So if you want async, you are also required to be on the 'first class subscriptions' side of the 'reaqtive' dimension.) These are useful in distributed scenarios, where establishing a subscription might entail communicating with an external service, an inherently asynchronous operation.</p>
<p>Each of these dimensions has a role to play in how Reaqtor builds on the capabilities of Rx, as we'll see in the final two parts.</p>
<p>In the fifth part of this series, <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-05-remotable-expressions.html">we'll examine remotable expressions</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Sequences, LINQ, Rx, &amp; Reaqtor Part 3: Rx</title>
      <description>In the third part in this series we investigate IObservable&lt;T&gt; and Rx.</description>
      <link>https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-03-rx.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-03-rx.html</guid>
      <pubDate>Fri, 14 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>To understand Reaqtor, it is necessary to understand Rx (the Reactive Extensions for .NET). And to understand Rx, it is necessary to understand how C# works with sequences of items. In this series I will outline the ideas at the heart of Reaqtor, and how they are handled in C#. So far we have looked at representing sequences of items with <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-01-sequences-and-ienumerable-of-t.html"><code>IEnumerable&lt;T&gt;</code></a>, its expression-tree-based cousin <code>IQueryable&lt;T&gt;</code>, and processing such sequences with <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-02-linq.html">LINQ</a>. Now we'll look at an alternative representation of the same abstraction.</p>
<p>A basic assumption made by both <code>IEnumerable&lt;T&gt;</code> and <code>IQueryable&lt;T&gt;</code> is that the information source (whether it's a data structure, an algorithm, or some sort of database) is able to provide information on demand. Code using these types asks for results either using <code>foreach</code>, or a LINQ operator that evaluates an entire query such as <code>ToList</code> or <code>ToArray</code>.</p>
<p>However, there is another way to model sequences of things: the source might produce items when it is good and ready to. This is sometimes referred to as 'push' and it's the model Rx uses. It models this with an interface called <code>IObservable&lt;T&gt;</code>.</p>
<p>The basic idea underpinning <code>IObservable&lt;T&gt;</code> is identical to that of <code>IEnumerable&lt;T&gt;</code>: both represent a sequence of items—one damn thing after another. The only difference is that the source gets to decide when the next item is produced.</p>
<p>The <code>IObservable&lt;T&gt;</code> interface is a sort of mirror image of <code>IEnumerable&lt;T&gt;</code>. Just as the latter has a corresponding <code>IEnumerator&lt;T&gt;</code> interface used when iterating through the items, <code>IObservable&lt;T&gt;</code> has a corresponding <code>IObserver&lt;T&gt;</code>. But whereas with <code>IEnumerable&lt;T&gt;</code> you ask for an <code>IEnumerator&lt;T&gt;</code> when you're ready to start working through the sequence, with <code>IObservable&lt;T&gt;</code>, you must supply an <code>IObserver&lt;T&gt;</code> when you're ready for items, because the <code>IObservable&lt;T&gt;</code> is going to invoke methods on you for each item.</p>
<p><code>IObserver&lt;T&gt;</code> has three methods: <code>OnNext(T)</code>, which the source invokes for each item it produces, <code>OnCompleted</code>, which it invokes to tell you the sequence has finished (the logical equivalent of <code>IEnumerator&lt;T&gt;.MoveNext()</code> returning <code>false</code>), and <code>OnError</code>, which it invokes to report an error (the logical equivalent of the <code>MoveNext()</code> method throwing an exception).</p>
<p>So enumerables and observables are logically equivalent (to the extent that the Rx libraries provide adapters that can convert from one to the other). It is just that sometimes, one will be a more natural way to represent some sequence than the other. <code>IObservable&lt;T&gt;</code> is the more natural way to represent events.</p>
<p>Rx includes a complete LINQ provider. More than complete in fact: in addition to all the operators available in other LINQ providers, Rx adds several new ones. (The team also released Ix, the &quot;Interactive Extensions for .NET&quot; which essentially provides versions of all these additional operators for <code>IEnumerable&lt;T&gt;</code> and <code>IQueryable&lt;T&gt;</code>.) So given some source of events, you can filter them with a <code>Where</code> clause, or do any of the other things LINQ supports.</p>
<p>Rx's 'push' world offers a particular distinction that we have also seen in the 'pull' world with <code>IEnumerable&lt;T&gt;</code> vs <code>IQueryable&lt;T&gt;</code>: in addition to <code>IObservable&lt;T&gt;</code>, Rx also defines <code>IQbservable&lt;T&gt;</code> (note the 'Q'). This is essentially a version of <code>IObservable&lt;T&gt;</code> but one where all the LINQ operators take lambdas in the expression tree form (whereas for a regular <code>IObservable&lt;T&gt;</code> the standard operators all take ordinary delegates—references to methods).</p>
<p>In the fourth part of this series, <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-04-reaqtive.html">we'll take a look at Reaqtive</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Sequences, LINQ, Rx, &amp; Reaqtor Part 2: LINQ</title>
      <description>In the second part in this series we delve deeper into LINQ and understand IQueryable&lt;T&gt;.</description>
      <link>https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-02-linq.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-02-linq.html</guid>
      <pubDate>Thu, 13 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>To understand Reaqtor, it is necessary to understand Rx (the Reactive Extensions for .NET). And to understand Rx, it is necessary to understand how C# works with sequences of items. In this series I will outline the ideas at the heart of Reaqtor, and how they are handled in C#.</p>
<p>Version 3.5 of the .NET Framework added a set of features which, amongst other things, made it significantly easier to work with sets of items. The features were known, collectively, as LINQ: Language Integrated Query. The headline capability of LINQ didn't obviously seem to have anything to do with <code>IEnumerable&lt;T&gt;</code>: its most touted feature was the ability to write database queries directly in C#, e.g.:</p>
<pre><code class="language-csharp">var openOrderIds =
    from order in dbContext.Orders
    where order.Status == OrderStatus.Open
    select order.Id;
</code></pre>
<p>Such queries could be translated at runtime into SQL. So although this code uses C#'s <code>==</code> operator in a way that appears to be inspecting the <code>Status</code> field of every <code>order</code>, in practice that will be converted into a SQL <code>WHERE</code> clause, meaning that the filtering will in fact be performed by the database server (which is generally what you want—downloading an entire copy of a table and then picking out the items you want is almost always a mistake).</p>
<p>However, while the marketing at the time put the spotlight on relational database support, the real power of LINQ came from the fact that none of the features added to support it had anything to do with databases. The new language features (new in 2008, that is) at work in that code snippet are:</p>
<ul>
<li>A query syntax</li>
<li>A set of standard 'operators' for performing operations over sets of data</li>
<li>Lambdas, i.e. the ability to write an expression whose value is a function</li>
<li>The option to have the compiler translate lambdas into data structures describing those expressions instead of runnable code</li>
</ul>
<p>It's the first of these that makes examples like the one above most resemble database queries. It's arguably also the least interesting, because you could remove it from the language without losing any of the functionality LINQ enables. Moreover, it obscures things a little—it's not obvious that the other features in that list are in use because of the way query syntax hides certain details. (Some people insist on not using query syntax for this reason. I think that's overkill because there are some situations in which query syntax enables simpler code that is easier to read, particularly in scenarios where <code>let</code> clauses are useful.)</p>
<p>The C# compiler translates queries into a series of method calls at compile time, with each call being invoked on the return value of the preceding one, leading to a chain of method calls. The query shown above is equivalent to this:</p>
<pre><code class="language-csharp">var openOrders = dbContext
    .Orders
    .Where(order =&gt; order.Status == OrderStatus.Open)
    .Select(order =&gt; order.Id);
</code></pre>
<p>If you were to inspect the output of the compiler for this and the previous snippet you would not be able to tell which of the results came from which input—the compiler simply translates the first form into the second form before going on to compile the code. This is why the query syntax isn't hugely interesting—it just provides a different look for your code.</p>
<p>In this second form, we can now see the operators more clearly: the <code>Where</code> and <code>Select</code> methods are examples of LINQ operators. A LINQ operator is not a language feature—it's more of a convention: for each operator there is a standard name for the method, some expected behaviour, and a particular method signature. (In some cases, there might be multiple standard signatures, in which case the methods will have overloads for each form).</p>
<p>For example, take the <code>Where</code> operator. The expected behaviour is that this will filter the items: the operator takes a filter function which must accept a single input—an item of whatever type the data set contains—and return a <code>bool</code>. If this function returns true for any particular item, that item will be included, and if it returns false, that item will be filtered out.</p>
<p>You might be wondering at this point &quot;How is this a 'convention'? Isn't this just a method?&quot; The answer is that there are many different implementations of the <code>Where</code> operator. The one you get depends entirely on the type of data set that you invoke it on. In the snippets above we are invoking <code>Where</code> on <code>dbContext.Orders</code>, and since I've not yet made it clear what that actually is, it's not yet possible to tell exactly which implementation of LINQ we're going to get.</p>
<p>So let's get clear.</p>
<p>Imagine <code>dbContext</code> is an Entity Framework context object, and its <code>Orders</code> property represents a particular table in the database. In that case, <code>Orders</code> would implement the <code>IQueryable&lt;Order&gt;</code> interface, an instance of the generic <code>IQueryable&lt;T&gt;</code> interface. This represents something slightly more abstract than <code>IEnumerable&lt;T&gt;</code>: it is some set of items of type T. One important distinction is that unlike with <code>IEnumerable&lt;T&gt;</code> there is no presumption of ordering. (This matters if the data set is ultimately a table in a database, because queries may well be executed in parallel, or in some cunning highly optimized way that means the ordering of elements is essentially unknowable while the query is in progress.) And the other important distinction is that an <code>IQueryable&lt;T&gt;</code> gets to decide exactly how queries are ultimately processed.</p>
<p>To expand on that last point, it's important to understand that there are several different LINQ implementations. Microsoft seems not to use these terms so much any more, but when LINQ was first introduced, they talked about &quot;LINQ to Objects&quot;, &quot;LINQ to SQL&quot;, and &quot;LINQ to XML&quot; and LINQ was designed explicitly to be open, so that anyone could implement their own &quot;LINQ to Something&quot;.</p>
<p>The particular implementation of LINQ you get depends first of all on the static type of the object on which you invoke the operator. For example, if you invoke <code>Where</code> on something that implements <code>IEnumerable&lt;T&gt;</code>, this ends up invoking the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where"><code>Enumerable.Where</code></a> extension method, and you are now using LINQ to Objects. If on the other hand you invoke it on something that implements <code>IQueryable&lt;T&gt;</code> then you end up invoking the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.queryable.where"><code>Queryable.Where</code></a> extension method, at which point the target object can decide at runtime exactly how to process the query. (And if you are writing your own &quot;LINQ to Whatever&quot; then you get to implement the <code>Where</code> method yourself, as either a member of, or an extension method for the target type.)</p>
<p><code>IQueryable&lt;T&gt;</code> is a special case, and a slightly odd one on first inspection: if it ends up letting the target object decide exactly what to do, then what's the point of it? Why not just have the target object implement <code>Where</code> (and any other operators it wishes to support) directly? Well part of the answer is that by having a standard interface, it becomes possible to write code that does things with types that support LINQ, without needing to know what those types are. But in that case, why doesn't absolutely everything use it? What's the point of <code>IEnumerable&lt;T&gt;</code> if we have the more general purpose <code>IQueryable&lt;T&gt;</code>?</p>
<p>To understand why, it's worth looking at a difference between how standard operators look on these two types. Here's the method signature of the LINQ to Objects version of <code>Where</code>, supplied by the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable"><code>Enumerable</code></a> class:</p>
<pre><code class="language-csharp">public static IEnumerable&lt;T&gt; Where&lt;T&gt;(
    this IEnumerable&lt;T&gt; source,
    Func&lt;T, bool&gt; predicate)
</code></pre>
<p>The <code>this</code> keyword on the first argument makes this an extension method, meaning the C# compiler will let you invoke this method directly on anything that implements <code>IEnumerable&lt;T&gt;</code> as though it were a member of that interface, even though it isn't really. And then the interesting part is the second argument: the predicate that determines whether each item should be let through. This is of type <code>Func&lt;T, bool&gt;</code> and that's an ordinary delegate type—this argument should essentially be a reference to a function.</p>
<p>So if I write this:</p>
<pre><code class="language-csharp">var openOrders =
    someIEnumerableOfOrders
    .Where(order =&gt; order.Status == OrderStatus.Open);
</code></pre>
<p>the compiler will turn that into something like this:</p>
<pre><code class="language-csharp">var openOrders =
    someIEnumerableOfOrders
    .Where(FilterMethod);

...

private static bool FilterMethod(Order order)
{
    return order.Status == OrderStatus.Open;
}
</code></pre>
<p>So it takes that lambda expression I wrote as the argument to <code>Where</code>, turns it into a method, and then passes a reference to that method. So this is ordinary executable code. Now let's look at the <code>IQueryable&lt;T&gt;</code> version of <code>Where</code>:</p>
<pre><code class="language-csharp">public static IQueryable&lt;T&gt; Where&lt;T&gt;(
    this IQueryable&lt;T&gt; source,
    Expression&lt;Func&lt;T, bool&gt;&gt; predicate)
</code></pre>
<p>Aside from the obvious difference that this deals with <code>IQueryable&lt;T&gt;</code> and not <code>IEnumerable&lt;T&gt;</code>, there's a more subtle difference: the predicate argument is now of type <code>Expression&lt;Func&lt;T, bool&gt;&gt;</code>. The significance of this is that it tells the compiler to do something completely different. Instead of wanting a reference to a method, this form of <code>Where</code> operator says that it wants a data structure describing the expression. So the compiler turns this:</p>
<pre><code class="language-csharp">var openOrders = 
    someIQueryableOfOrders
    .Where(order =&gt; order.Status == OrderStatus.Open);
</code></pre>
<p>into something more like this:</p>
<pre><code class="language-csharp">var orderParam = Expression.Parameter(typeof(Order), &quot;order&quot;);
var predicate = Expression.Lambda&lt;Func&lt;Order, bool&gt;&gt;(
    Expression.Equal(
        Expression.Property(orderParam, &quot;Status&quot;),
        Expression.Constant(OrderStatus.Open)),
    orderParam);
var openOrders =
    someIQueryableOfOrders.Where(predicate);
</code></pre>
<p>In fact it's slightly more complex than that due to the way <code>enum</code> comparisons get handled, but this illustrates the basic idea: the compiler generates code which, when executed at runtime, creates a tree of objects representing the structure of the expression you originally wrote.</p>
<p>So in this case, our <code>order =&gt; order.Status == OrderStatus.Open</code> gets turned into an object representing a lambda expression with a single parameter called <code>order</code> of type <code>Order</code>, and whose body is an object representing an equality comparison that compares the result of fetching the order parameter's <code>Status</code> property with the constant value <code>OrderStatus.Open</code>.</p>
<p>Anything implementing <code>IQueryable&lt;T&gt;</code> will end up with code like this when you use LINQ operators that take lambdas—they all compile into the expression tree form. And then the source object implementing <code>IQueryable&lt;T&gt;</code> gets to decide how to process that expression tree.</p>
<p>If the source represents some table in a relational database as in our original query example, it will convert this expression into a SQL query which it will then send to the database.</p>
<p>Objects representing other sources could do something similar—for example, something representing a collection in a CosmosDB could convert an expression into a query that CosmosDB can process.</p>
<p>The upshot of all this is that LINQ defines a set of operators (which goes well beyond the simple filtering of the <code>Where</code> operator shown in this example—you can also do grouping, ordering, existential predicates, and numerous other jobs). Any type that supports LINQ can then offer some or all of these operators, and it can then implement them in whatever fashion it sees fit—it might simply run code on collections of objects (which is what LINQ to Objects does) but it might also translate queries into a different language to be executed remotely.</p>
<h2 id="when-execution-occurs">When Execution Occurs</h2>
<p>In general, LINQ operators don't do anything immediately. When using either <code>IEnumerable&lt;T&gt;</code> or <code>IQueryable&lt;T&gt;</code> they only do work when you ask them for objects. For <code>IEnumerable&lt;T&gt;</code> this is important because it makes it possible to work with infinite sequences. If a <code>Where</code> clause attempted to perform filtering the moment you call the <code>Where</code> method, it wouldn't work on an infinite sequence because it would never finish. But in fact LINQ to Objects works on demand—when you chain together a series of operators, you end up with an <code>IEnumerable&lt;T&gt;</code> that only starts work when you obtain an enumerator and then call MoveNext().</p>
<p>In general, <code>IQueryable&lt;T&gt;</code> implementations also defer their work although they have an additional motivation: in cases where they translate the query into something else (e.g. SQL) they want to wait until they know you've finished building the query. Until you actually start asking for results, a LINQ provider has no way of knowing if you're planning to append any more operators. Take this example from earlier:</p>
<pre><code class="language-csharp">var openOrders =
    dbContext.Orders
    .Where(order =&gt; order.Status == OrderStatus.Open)
    .Select(order =&gt; order.Id);
</code></pre>
<p>We could also have written this thus:</p>
<pre><code class="language-csharp">var orders = dbContext.Orders;
var whereQuery = orders.Where(order =&gt; order.Status == OrderStatus.Open);
var openOrders = whereQuery.Select(order =&gt; order.Id);
</code></pre>
<p>This has exactly the same effect, we've just put the result of each operator into a named variable rather than going on to invoke a method on it directly. If operators ran immediately, the <code>Where</code> operator would have run before the <code>Select</code>, and that's bad: what we would actually want this to do is run as a single SQL query that combines the <code>Where</code> and <code>Select</code>, and only returns the ids.</p>
<p>So when you use a LINQ operator, you don't normally get actual results back. You usually get a new instance of the same sort of data set you applied the operator to. For example, applying an operator to an <code>IEnumerable&lt;T&gt;</code> produces an <code>IEnumerable&lt;R&gt;</code> (where <code>R</code> may or may not be the same as <code>T</code> because some operators change the type—<code>Select</code> does that, for example).</p>
<p>This is called deferred execution: LINQ queries (for all widely used LINQ providers) don't do any work until you start asking them for results, which you typically do either by using a <code>foreach</code> loop on them, or by using LINQ's <code>ToList</code> operator, which evaluates the query and returns the results in a <code>List&lt;T&gt;</code>. (<code>ToList</code> is one of the few standard LINQ operators that does in fact execute immediately.)</p>
<p>In short, with the LINQ providers we've seen so far, operators do work when you pull information out of them. However, there is another way.</p>
<p>In the third part of this series, <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-03-rx.html">we'll delve into Rx</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Sequences, LINQ, Rx, &amp; Reaqtor Part 1: Sequences and IEnumerable&lt;T&gt;</title>
      <description>In the first part of this series we explore the basic building blocks of Reaqtor—IEnumerable&lt;T&gt;.</description>
      <link>https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-01-sequences-and-ienumerable-of-t.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/blog/2021/05/sequences-linq-rx-reaqtor-part-01-sequences-and-ienumerable-of-t.html</guid>
      <pubDate>Wed, 12 May 2021 06:30:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>To understand Reaqtor, it is necessary to understand Rx (the Reactive Extensions for .NET). And to understand Rx, it is necessary to understand how C# works with sequences of items. In this series I will outline the ideas at the heart of Reaqtor, and how they are handled in C#.</p>
<h2 id="sequences-and-ienumerablet">Sequences and IEnumerable&lt;T&gt;</h2>
<p>At Reaqtor's heart lies an incredibly simple abstraction: a sequence of items. It's just <a href="https://quoteinvestigator.com/2015/09/02/life-one/">one damn thing after another</a>, so to speak.</p>
<p>C# has had integrated language support for sequences of items from day one. Perhaps the most obvious example is the array, but that's not the most important: there are many different ways in which one might want to make a sequence of items, and while arrays matter because they are an intrinsic feature of the .NET runtime, there are many reasons you might not always want to use one. For example, .NET arrays have a fixed size. For this reason, we might often instead choose something like <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1"><code>List&lt;T&gt;</code></a>, a generic type that provides something strongly resembling a resizable array.</p>
<p>But there are often good reasons to use something that does not much resemble a dynamic array. Perhaps you need to support very long sequences with the ability to insert new items in the middle. Array-like structures can't do this efficiently, because if you want to insert an item in the middle (or at the start) of an array, you need to move all the items after the insertion point along by one position to make room for the new item. A linked list, on the other hand, is able to support insertion extremely cheaply. But it is absolutely terrible at finding the nth item, something arrays are extremely good at. This is why we have multiple data structures—there are many ways of representing things, each with its own strengths and weaknesses.</p>
<p>However, it is useful to be able to write code that doesn't need to concern itself with the details of the data structure. For example, if you want to calculate the sum of all the integers in a sequence, it's handy to be able to write code that works independently of the exact representation. And you can in C#—you can write this sort of thing:</p>
<pre><code class="language-csharp">int total = 0;
foreach (int i in sequence)
{
    total += i;
}
</code></pre>
<p>This code can work across all sorts of different representations—it will work with native .NET arrays, or with <code>List&lt;T&gt;</code>, but also with collections that use radically different data structures such as <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.linkedlist-1"><code>LinkedList&lt;T&gt;</code></a>, <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1"><code>HashSet&lt;T&gt;</code></a>, or <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablelist-1"><code>ImmutableList&lt;T&gt;</code></a>.</p>
<p>This is possible because the <code>foreach</code> statement recognizes a pattern embodied by the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1"><code>IEnumerable&lt;T&gt;</code></a> interface. All of the aforementioned collection types implement <code>IEnumerable&lt;T&gt;</code> and can therefore be consumed by a <code>foreach</code> loop. (Language pedants might point out that <code>IEnumerable&lt;T&gt;</code> is not strictly a requirement, because the compiler will in fact accept any type that offers the necessary members. I would respond by suggesting said pedants reread the carefully worded first sentence of this paragraph, which accommodates this fact without letting it get in the way of things. Experienced writers will then note that I've blown it by drawing attention to the issue in this parenthetical; I have no defence on that point. In practice, <code>IEnumerable&lt;T&gt;</code> matters because as we will see, even though the C# <code>foreach</code> keyword is pretty flexible, many language features insist on this particular interface. And in practice, it's more or less ubiquitous—anything you might want to iterate over with <code>foreach</code> is likely to implement <code>IEnumerable&lt;T&gt;</code>.)</p>
<p>An important aspect of <code>IEnumerable&lt;T&gt;</code> is that it does not offer random access—it doesn't have an indexer enabling you to retrieve, say, the 1000th item. The way it works is that you call its <code>GetEnumerator()</code> method, which returns an <code>IEnumerator&lt;T&gt;</code>, which you then ask for items by repeatedly calling <code>MoveNext()</code>. If <code>MoveNext()</code> returns false, that means you've reached the end of the sequence. (Sometimes sequences are empty, in which case the very first call to <code>MoveNext()</code> will return false.) If it returns true, that means a new item is available, which you can then retrieve from the enumerator's <code>Result</code> property. Once you're done with an enumerator (either because you reached the end, or because you've decided not to fetch all the elements) you call <code>Dispose()</code> on it. The <code>foreach</code> keyword generates all this code for you.</p>
<p>This one-at-a-time behaviour can sometimes be a little frustrating for the consumer of an <code>IEnumerable&lt;T&gt;</code> but it enables considerable variety of implementation. It makes it easy for a linked list to implement, for example.</p>
<p>A more subtle upshot of the nature of <code>IEnumerable&lt;T&gt;</code> is that it means the sequence of objects doesn't necessarily have to exist in advance. For example, you could write an <code>IEnumerable&lt;int&gt;</code> that returns numbers produced by the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.random"><code>Random</code></a> class. Sequences that produce their items on demand like this are sometimes known as 'lazy' because they don't do work until they absolutely have to. Another interesting characteristic of this hypothetical random number generating <code>IEnumerable&lt;T&gt;</code> is that it never needs to end—you could make its <code>MoveNext()</code> return false after some number of calls, but you don't have to—you could just hardwire <code>MoveNext()</code> to return true, because you can carry on producing random numbers indefinitely. This could be described as an 'infinite' sequence. Infinite sequences are necessarily lazy (because any attempt to produce all the items up front would run out of memory), although not all lazy sequences are infinite.</p>
<p>So in summary, <code>IEnumerable&lt;T&gt;</code> is the normal way in .NET to represent sequences of items. Collection types (<code>List&lt;T&gt;</code>, <code>LinkedList&lt;T&gt;</code> etc.) almost invariably implement it, but it's also possible to write lazy implementations that produce items on demand, possibly without end.</p>
<p>In the second part of this series, <a href="/blog/2021/05/sequences-linq-rx-reaqtor-part-02-linq.html">we'll investigate LINQ</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Reactive Extensions for .NET</title>
      <description>&lt;p&gt;The Reactive Extensions for .NET (&amp;quot;Rx&amp;quot; for short) are a set of libraries for working with asynchronous and event-based information sources. While Rx has become widely adopted in client-side code, its roots are in highly scalable server-side processing.&lt;/p&gt;
&lt;p&gt;In this talk, Ian Griffiths shows why Rx should be a critical part of any .NET developer's toolbox, and shows a real-world application that illustrates how the powerful processing and orchestration facilities Rx provides can be applied to collect and process data in edge devices and then stream the high-value events to an Azure IoT hub for further analysis in the cloud.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/reactive-extensions-for-dotnet.html</link>
      <author>Ian Griffiths</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/reactive-extensions-for-dotnet.html</guid>
      <pubDate>Thu, 06 Aug 2020 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>The Reactive Extensions for .NET (&quot;Rx&quot; for short) are a set of libraries for working with asynchronous and event-based information sources. While Rx has become widely adopted in client-side code, its roots are in highly scalable server-side processing.</p>
<p>In this talk, Ian Griffiths shows why Rx should be a critical part of any .NET developer's toolbox, and shows a real-world application that illustrates how the powerful processing and orchestration facilities Rx provides can be applied to collect and process data in edge devices and then stream the high-value events to an Azure IoT hub for further analysis in the cloud.</p>
<p><a href="https://www.youtube.com/watch?v=6yjl_h7-WYA"><img src="/assets/images/talks/dotnetsheff-the-reactive-extensions-for-dotnet.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Cloud-Scale Event Processing with the Reactive Extensions</title>
      <description>&lt;p&gt;Come and see how reactive programming is used to build cloud-scale, low-latency, distributed event processing systems at Microsoft, powering end-user experiences such as the personal digital assistant 'Cortana'.&lt;/p&gt;
&lt;p&gt;In this session Bart shows what it took to bring the concepts of Reactive Extensions (Rx) to the cloud to deal with latency, scale, reliability, and other concerns.&lt;/p&gt;
&lt;p&gt;You'll also learn about the core API abstractions that are used to represent event processing systems of any size across our stack, including the cloud as well as devices and sensors.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/cloud-scale-event-processing-with-the-reactive-extensions.html</link>
      <author>Bart De Smet</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/cloud-scale-event-processing-with-the-reactive-extensions.html</guid>
      <pubDate>Tue, 30 Jun 2015 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Come and see how reactive programming is used to build cloud-scale, low-latency, distributed event processing systems at Microsoft, powering end-user experiences such as the personal digital assistant 'Cortana'.</p>
<p>In this session Bart shows what it took to bring the concepts of Reactive Extensions (Rx) to the cloud to deal with latency, scale, reliability, and other concerns.</p>
<p>You'll also learn about the core API abstractions that are used to represent event processing systems of any size across our stack, including the cloud as well as devices and sensors.</p>
<p><a href="https://www.youtube.com/watch?v=Iev_leBGJ2I"><img src="/assets/images/talks/cloud-scale-event-processing-with-rx.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Reaqtor &amp; Cortana</title>
      <link>https://reaqtive.net/talks/reaqtor-and-cortana.html</link>
      <author>Bart De Smet</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/reaqtor-and-cortana.html</guid>
      <pubDate>Tue, 09 Sep 2014 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://www.youtube.com/watch?v=Pw3yjt7SyMk"><img src="/assets/images/talks/channel9-reaqtor-and-cortana.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>AMA: Reactive Extensions &amp; LINQ</title>
      <description>&lt;p&gt;In this session at Tech-Ed 2012 Bart De Smet answers questions about Reactive Extensions and LINQ.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/ama-reactive-extensions-and-linq.html</link>
      <author>Bart De Smet</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/ama-reactive-extensions-and-linq.html</guid>
      <pubDate>Tue, 26 Jun 2012 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>In this session at Tech-Ed 2012 Bart De Smet answers questions about Reactive Extensions and LINQ.</p>
<p><a href="https://www.youtube.com/watch?v=xidX4TDf5JE"><img src="/assets/images/talks/tech-ed-2012-ama-rx-and-linq.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>IQbservable - The Dual of IQueryable</title>
      <link>https://reaqtive.net/talks/iqbservable-the-dual-of-iqueryable.html</link>
      <author>Bart De Smet</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/iqbservable-the-dual-of-iqueryable.html</guid>
      <pubDate>Tue, 18 May 2010 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://www.youtube.com/watch?v=DqrUpLEQ-6I"><img src="/assets/images/talks/channel9-iqbservable-the-dual-of-iqueryable.jpg"/></a></p>]]></content:encoded>
    </item>
    <item>
      <title>AMA: C#, Rx, LINQ &amp; Event Processing</title>
      <description>&lt;p&gt;In this AMA, .NET Rocks host Richard Campbell interviewed Bill Wagner and Bart De Smet, and took questions from the audience.&lt;/p&gt;</description>
      <link>https://reaqtive.net/talks/ama-csharp-rx-linq-and-event-processing.html</link>
      <author>Bart De Smet</author>
      <guid isPermaLink="true">https://reaqtive.net/talks/ama-csharp-rx-linq-and-event-processing.html</guid>
      <pubDate>Tue, 03 Nov 2009 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>In this AMA, .NET Rocks host Richard Campbell interviewed Bill Wagner and Bart De Smet, and took questions from the audience.</p>
<p><a href="https://www.youtube.com/watch?v=1YS-_ihoUkY"><img src="/assets/images/talks/ndc-sydney-2017-ama-csharp-rx-linq-event-processing.jpg"/></a></p>]]></content:encoded>
    </item>
  </channel>
</rss>