Main

On .NET Live - Modernizing Rx.NET

Reactive Extensions for .NET (Rx.NET) is a library for event-driven programming with a composable, declarative model. In this week's episode, community MVP Ian Griffiths visits to show us the latest developments on this popular .NET project. Chapters: 00:00 Countdown 03:04 Welcome to On .NET Live 03:48 Intro Ian Griffiths 05:00 What is Rx.NET and how is it used 22:25 Demo 40:00 ReactiveUI 01:00:27 Wrap Resource links: Intro to RX http://introtorx.com Reaqtor https://reaqtive.net/ IObservableT Interface https://aka.ms/IobservableT Polyglot Notebooks in VS Code https://aka.ms/VSCode/PolyglotNotebooks Featuring: Ian Griffiths (@idg10), David Pine (@davidpine7), Cecil Phillip (@CecilPhillip), Maira Wenzel #rx #reactive-extensions

dotnet

Streamed 7 months ago

[MUSIC] >> Hello, everyone. It's nice to be back here on another episode of On.NET Live. We will have 60 minutes of unscripted.NET entertainment. Our mission is to empower the.NET community to achieve more. I see we have people from all over the world, but I'm your host Maira Wenzel with my co-host David Pine. >> Hello. >> Cecile Philip. >> Hey, everybody. >> I'd like to welcome today's guest Ian Griffiths who's going to be talking about modernizing our RX.NET. But before we jump into that, I wa
nt you to just introduce yourself and share a little bit about yourself for us. >> Hello. My name's Ian Griffiths, and thank you very much for having me on. I am a longtime.NET guy so I've been using.NET since before first person one shipped. I am the author of The O'Reilly programming C-Sharp series of books. I was one of the first plural sites online content authors, and I do a lot of consulting. I used to specialize in WPF work, these days I've moved more into data analytics-type spaces. Thes
e days I work for a company called Engine who are also the sponsors now the RX.NET code base, so it's thanks to them, thanks to my bosses that we actually are able to talk about this today. I have a deep level of computing, I've been playing with computers since I was about six, which takes us back a very long way given how great my beard is but that's me >> Awesome. I like the extensive curriculum. Thanks for your boss for sponsoring your project. But let's start, maybe, from the beginning and
share with our viewers that maybe are not familiar with RX.NET and like why does he do, what it is, and then we can go from there. >> Yes. RX, in my view, is as fundamental an idea as something like an array. It really is that basic, it does something that is vitally important to computing and is of the years been undeserved to be honest. I would say RX is useful in any program where things happen. You write programs where things happen. Let's be honest, not all programs are like that, there's a
lot of stuff that works around, batch processing where data is there and you do stuff to the data and new data that comes out of it, nothing's really happening. There's data there, there's data there afterwards, it's a process, so not everything needs this. But certainly, any user interface-based program has absolutely huge amounts of things happening, and you need stuff to happen in response to that, and that's possibly where RX is best known. But it's also really useful in things like Interne
t of Things type applications. At Engine, we've worked with it in utility companies for example, so we worked with a major broadband network provider using RX to represent the diagnostic information that the broadband network was able to provide, so you have literally millions of customers with broadband devices in their homes, and every single one of those routers in people's houses is able to generate huge quantities of telemetry about how things are going, and they wanted to do things like an
ticipate when there were failure's coming in the network, but also to be able to do multi-level analysis so that they could tell when they were starting to get a bunch of faults from certain devices whether it was just at home, someone accidentally spill bear into their ramp or something, or was it actually a fault the exchange. Because what you don't want to do is send 30 people out in advance to 30 houses when there's actually a fire at the exchange, that's the wrong response. That ability to
manage large quantities of individual information streams and perform analytics that work both at the global level but also are able to remain active at the individual source level as well. That's the thing that RX is able to model in a way that few of the things can. It's, like I say, useful anywhere, things happen and you need to do something about that. It's fundamentally important. It's amazing in a way that computer languages didn't have a way of doing this in the past. Microsoft invented t
his back in the late 2000, so around about 2008/2009, this stuff was burrowing away. I honestly think it's one of the most significant contributions that Microsoft has made to the world of computing, and you can see how big it is by the extent to which it has been embraced outside of.NET. You look in the JavaScript world in particular, RX is extremely heavily used, because it is just such a perfect way of dealing with this ubiquitous problem. So I like it in case you can't file >> That's somethi
ng that I wanted to tap in on and you said fundamental, and when I think about Fundamental.NET, I think about things like Link as an example. At least in 2023 Link is a fundamental thing, and when I look at RX and I look at Link and you turn him sideways and squint a little bit you look like the same thing. They follow similar models and have similar API structures. But I feel like Link has been maybe just because it's in the box, Link has been more like adopted by a lot of.NET developers. Why d
on't you think the same thing has happened with RX in the.NET space? >> I would start by saying that Link is many things. There's Link to objects, there's Link to Entity Framework, there's Link to XML, and you can use Link and all sorts of things and RX was one particular Link provider. But I think the way I would cost, but I think you're saying is that of all the Link providers out there, whether it's data access or the relational database or whether it's just working with objects in memory. RX
has been less strongly adopted I think. Why is that? I think part of that I would say it's probably that is not in the box, it's not a thing that's right there, you have to go and look for it. I also think that there's a learning curve. It's not necessarily the easiest thing to understand how to use effectively. It's a thing where once people get it, they tend to absolutely love it, but there's a bit of a journey getting to that point. You have something of a eureka moment, but you're so scared
, this is how I'm supposed to use it because it feels very different from how we're accustomed to dealing with bunches of things that happen. Because as developers, a lot of us are accustomed imperative code, does one thing after another. If you're processing events that happen one thing after another, it feels like you just do that with normal looking code. But actually Link in general and our RX is no exception to this, encourages a much more declarative approach where you describe the way you
're processing sets of information and in a relational database that might turn into a query where the database is processing into our table at a time in our exit turns into sequence processing, but it's expressed declaratively. I think it takes a while to get used to in the same way, but I think relational database programming takes awhile to understand. It's so ubiquitous, it's so common that a lot of people understand. Although I think actually, maybe these days with document database is beco
ming more popular and it's now pushing another [inaudible] to the mobile. Maybe not all developers do understand relational databases in the way that they probably did 15 years ago, but I think it's an interesting example because until you understand how to denormalize your data and how to structure things in a way that works the way the database once you to work, it's actually quite hard to be effective, but once you get it it's enormously powerful and I think RX is that thing. I think it is th
e combination of the 30 steep learning curve and the fact that it is never quite come deceived as mainstream. Those two things have probably meant that it's always been a little bit less strong relation. Those are part of the main reasons. But then it has been adopted in the JavaScript world and I think that might be partly because one of the easiest ways to see why RX is useful is any user interface application. Because there you are absolutely dealing with events and there is a very visual out
come of doing so. You can see right away that this connection from this source to that output has had the effect that you want it, and so it becomes really easy to experiment with it and to understand whether what you've done work, so you have this very tight feedback loop that helps you to learn it if you're doing user-interface programming. Whereas I think it is harder to learn in other environments I think, so I think that probably is part of the reason as well >> I guess when I think about w
here I've seen it used and I agree with you 100 percent. I've seen a lot in those UI based things. Whether it's UI in the browser or on a mobile app or a desktop application. I would even say when I look at it from a JavaScript perspective, a lot of the times if anyone here is an angular developer and you're using the http client, there's a lot of RX things attached to it. But the thing I was always surprised about was we as data developers are looking at other people use it, they have figured i
t out, but for some reason maybe we just haven't cared enough to attach to it. Because I would assume that they would have less information than we did, because it came from us first, we gave it to you, thank you very much, but in now we're just watching other people do it. I agree with you. I think it's an education thing, I think it's where am I going to use it thing, show me how to do the thing, and then I'll figure it out after that. As I'm hoping part is conversation would be a little bit o
f you talking to us about what are things people need to know about RX on a fundamental level, and then also what are some of the new things y'all are doing to modernize it a little bit. >> On that, one thing that I wanted to talk about is that we are trying to do a better job of education. Quite awhile ago, there was a guy, I think his name is Lee Campbell, let me just check I've got the right name for him. I've lost the page I had his name written down, I think it's Lee Campbell. He wrote a th
ing called Intro to Rx.com and that's still up there, but it was written about 10 years ago, and so it feels a little bit out of date. We had engine as well as taking over the ownership of the.NET projects up on GitHub we also approached him and said would you mind if we rewrote this? Would you mind if we updated this and brought it up to speed because it's a good starting point, but I think it's people have found it, so when we first announced the latest release of RX, some people on Reddit sai
d, well, I found this thing here, but it seems to be from 2012, what's going on? It's like we should probably fix that. Definitely, education is a big issue and as a book author, as a plural-sight author, and a former in-person instructor back when people used to learn things by going into a classroom and listening to someone, I really enjoy explaining stuff, I have a passion to teaching thing, so it's one of the things we are hoping to bring to this picture, it's getting better explanations out
there. >> I think we all work with documentation here in the path and we know how important it is to have that material. Part of the mission of this show is also to give that platform to folks to get their projects out there and have more visibility. I was wondering because I don't know a lot about the history of RX and you mentioned [inaudible], so is that something that started with Microsoft and then became a community project later? >> Yes, so it originates actually with a team called the C
loud Programmability Group. This was headed up, but one of the main people behind it was the same guy who invented Link actually. >> Whose name I've just blank Tom but he's a very well-known academic in the computing world, and he worked for Microsoft for quite a long time. He was also I partly involved in the development of async and await icon. >> They know is Erick Meyer was his name. >> I would say, Erick Meyer. Yes I can't believe I forgot his name that. Yes Erick Meyer, he was one of the b
ig brains behind this and while they were trying to do at the time the remits of that group was that Azure was coming at that point it was very new and one of the concerns Microsoft as a whole as a company was how on earth are people actually going to use this. It's incredibly path or having this Cloud platform that can do all things for you but how do you actually build software how are we going to tell people how to use this. One of the things they wanted to be able to do was to simplify devel
opment of software multiple different layers in the system. What they actually invents it looks a lot like what we now call blazar. They invented that 10 years before blaze a shift and I called cold it Valta and it was a very similar architecture. One of the things that they actually needed was this ability to pass events from one lab to another. If you had code running in a web browser on a mobile phone they wanted to be able to have events like we note new and live in.NET tidy things have happ
ened button click this has just been loaded. They wanted those to be able to flow across machine boundaries. If you wanted the logic to run in some tear in the Cloud you could do that but without having to suddenly go to a totally different programming model. Back in 15 years ago that wasn't an option if you wanted to go across the network you have to deal with sockets or at least http which is a totally different thing from a.NET event. They said well how could we build an abstraction that is a
ble to represent events like things but which is also formally well-defined enough that it would be possible to make it transfer across machine boundaries without losing anything. That was actually the goal that was actually the motivating idea behind developing RX in the first place. Then they develop the abstractions around this and the I observable and observer and devices that are the core of what RX means came out of that and that was the start of it and then they realized that actually in
a sense it's very similar to like an IEnumerable an observable sequence is just one thing after another. The only difference is that with an IEnumerable IE is the consumer say and now I'd like the next thing you foreach over it it's a so-called pull model. You pull the next item out of the collection when you're ready RX it's still just a sequence of objects the only thing that's changed. Is that the source is saying I've got to think for you now I've got another thing if you now it's pushing da
ta at you but it's still basically the same model. It's one thing after another it is a sequence of things and so they realized they could actually build the entire same set of link abstractions over RX as we're available for IEnumerable and then from that the RX project grew out. Now the Cloud programmability group turned into other things but this project survived and actually it was one of the first Microsoft Projects to be open sourced I believe. I think it was originally the ad occur founda
tion as it was back then and it was up on code Firefox I think. >> Firefox. >> Now it's on GitHub of course as you'd expect but it was on complex first. I think part of the reason that has endured is because it was designed for quite different scenarios for how it ultimately got used they had to come up with an idea that was going to engineer so abstractions that were actually really well founded and that would not pass the test of time and that I think actually is the key to its success. They r
eally thought about what the right abstraction was and that is the foundation of everything really good foundations are what enabled longevity. >> You talked earlier before about it being fundamental to almost every type of application you are developing. You're talking about the history we've got a question coming from Facebook. Mohammed's asking what are just the general benefits of using it differentiated IEumerable versus IObservable and one's pull-based ones push-based. What are the benefit
s? >> What are the benefits of using RX for event handling. I would say that the answer to that fall into two categories. One of which is that RX because it's system its eyes there's a standard way of doing things it's possible for thin to provide tools that solve certain problems generally. One problem that comes up with events in the user to faces for example is something tells you a thing has happened so let's say you've got I don't know some medical device monitor sends a message saying here
's the latest oxygen reading on this person's blood put something whatever it might be. The software needs to respond to this but that message could come into some random thread you've no idea what thread the library's going to give it to you on. Most user interface frameworks don't like that if you try and do things to the user interface on the wrong thread if you're lucky they'll throw an exception but in the worst case they might just break in subtle ways and just go a bit wrong thereafter. R
X is able to say well we have a way of solving that by saying you can just take any observable source. Say I would like to observe this source in this particular context so you can say I've got a WPF Window and I want to observe events from this source in that Windows dispatch. It'll make sure it goes onto the right thread and all the right things happen and as a different one for Windows forms. The Apollonia team that built one that works for that UI and there's one for UWP. Is anyone can write
their own because it's very clear what you do you just have to provide an RX operator to abides by all the rules and then does whatever you needed to do to deliver notifications into the right context. It's that orthogonality means you can separate outs an aspect of the problem like getting things onto the right threads. You can separate that out from what am I doing with my data. That then leads me on to the second part of my answer to this which is that one of the big things that RX enables i
s composition of different techniques and actually if I may I'd like to show an example of this to illustrate the thing I'm talking about. I've got a Visual Studio code here and I've got the polyglot notebook extension installed. I'm just going to run this notebook and I'm quickly going to tell would tell you what it does first before I start showing you the code. You can see I've got a map here and if I zoom in on Norway what's going to happen in a minute is we're going to start seeing lots of
little markers appear around the coast of Norway the senior my demo actually runs correctly. That are going to show me where ships sailing around the coast of Norway. I'm going to take a quick peek at the execution status of this to see if it is actually running how far have we got. It's taking 30 seconds to download a package from NuGet that is a good start for that. I'm going to close and reload this because that doesn't normally happen. Let's try again. That's very weird why is it already run
ning a program. I think this is going a bit weird so I'm going to quickly kill that and restarts it. If it will let me that's the problem with running your demos before you start to talk is that some signs they then don't work afterwards. This was that folder there. Let's see if this will work this time. I'm going to open up this notebook and hopefully this time it won't be under the impression that all the cells are already running. That is looking better if we can get past this one there we go
. Well since I've got had to go back to the start I'll tell you what it's doing. I'm going to run everything. This is using a library called ais.net which is also an open source library maintained by my employers I thank you again to you Engine for this. What this does is it connects to a public service generously provided by the Norwegian Government's who provide a thing you can subscribe to that tells you when ships are moving around on that coast. AIS is the automated identification system. >
> That's awesome. >> It's basically GPS receivers on ships are required by law to broadcast their location, their speed, their heading, and various other bits of information to operate in most international waters so anywhere you see ships you will be able to pick up AIS messages by just sticking appropriate receiver up in the air. The Norwegian Government just runs a service where you can connect to a well-known IP address and port number and start receiving messages. Our library provides a cli
ent on slope of this which then wraps it in RX so you get an RX observable stream of messages coming from ships moving around from whatever server you've attached from which is all of Norway in this case. We've then just loaded Bing Maps and if I scroll down I'm hoping there we go, do you see the little towers? >> Yeah that's awesome. >> That's a live data. That's all happening in real time. They gradually more and more what a pair because one of the challenging features of this data source is t
hat when they send messages they don't send all the information all the time. The several different types of messages a ship consent. There's a navigation message which will say I'm here I'm pointing this way I'm moving that way because when you're underwater those aren't always the same thing. I am going at the speeds and basic information like that. Don't always tell you the name because ships tend to move more often than they change their names and so it doesn't necessarily make sense to incl
ude the name in every single message that they sent. There's different messages. One of the challenges if you want to maintain a map like this is to reconcile those two diverse streams. It's like this thing I'm the Spirit hey you've just seen a pair. Well it's told us its location but it probably told us it's name a few minutes ago. We've had to hang on to that. Logically you've got a stream of My name is this type messages and you'll also get a stream of I I'm here messages and we want to recon
cile that onto the map to say I I'm here I and my name is this so I can label the things on the graph. We've achieved this using RX if I scroll down a little bit and start to show you what this looks like. I've had to do a certain amount of jewelry pottery to enable an interactive map inside a notebook. We'll just ignore all that code that's just to make things work inside of here live. This is a little complex but it's quite a good illustration of how you use RX. I'm just going to crank size up
a couple of notches right. That's the receiver host that's the AIS.NET library wrapper the engine provides an open source project and it has a message is property and if I mouse over that you can see it says I am and IObservable. For some reason the notebook doesn't show me the type of message I can tell you it's iObservable of AIS message. iObservable is the fundamental interface of RX. It is the thing that any source of events. >> Implements. This is a source of events, so I could subscribe t
o it. If I did subscribe to it, I would be somewhat overwhelmed. Actually, let me just quickly show you what that would look like. I've got a separate program here written in Visual Studio that uses the exact same source. >> Could you zoom in a little bit on this one, Ian? >> Yeah, sorry. >> Thank you. No, you're good. >> Let me get these things out of the way, so the spaces will use properly. I got a few different things in here I can show you. I'm going to show you first of all the rate at whi
ch messages are coming in. Comment that one and comment these ones out and run this. I hope it will tell me every, no, that's going to tell me every minute, that's far too slow for demo purposes let me back that one out. Let's do this 10 times a minute. Also, there was an error in there. Let's just lose that. Ready to go now. Every 0.1 minutes, I've asked this thing to tell me just how many messages it's received from that source. That's every six seconds 113, so multiply that by 10. This are so
mewhat 1,000 and 1,500 messages a second coming out of this source so relatively busy. There's quite a lot going on here. There's quite a lot to keep track of. If you just subscribe to this and just print out messages, it would be drowning in data and it will be completely incomprehensible. What we tend to do with Rx is that we use operators to manage the data. We can use various link operators to process it with a bit more sanity. I'll get back to the map. But I want to show this one first beca
use this shows things broken down in slightly more detail. If I uncomment this one, here I'm using GroupBy. This is a standard link operator you, get this in link to objects, you get this in link to entity framework, and so on. This basically says I got a bunch of things here, happens to be an observable sequence of AisMessages in this case, and I'd like to partition them into groups and I'd like to group them by the vessel identifier. The MMSI is something like I can never remember, marine mobi
le something information. The S probably doesn't stand for something but it may as well do. It's a unique identifier. Each ship has its own different ID, so what this does is it partitions the fire hose of messages coming from all the ships in Norway, it partitions them into groups with one group per ship so I get observables of that point. Every time it sees a ship with an ID it hasn't seen before my top-level observable is going to emit a new group for that ship and that ship alone. But that g
roup is then going to emit an AisMessage every single time that particular ship broadcast a new message. Then armed with this I can do things like ask, well, when does the ship change its status? I'm going to run this now because this actually produces messages quite slowly often. I'm going to move that off the screen while I talk about this and hopefully, it will produce a response by the time I'm done. What are we doing here? Well, here I'm saying, well, I'm aware that there are several differ
ent types of messages. I'm going to focus in on a certain type of message that I happen to know reports the navigation status of a ship. That tells you things like is it mod? Is it moving under its own engine power? Is it sailing somewhere? Is it being towed by a tug? Is it fishing? It's got lots of different well-defined status as the ship can be in. The navigation messages so the ones that tell you where you are, which way you're pointing, how fast you're going, also happen to report this navi
gation status as well. But it doesn't change very often. Ships don't tend to flip back and forth between being moored and anchored and sailing and fishing a lot often. Say if you think about what a sailing boat does it will be moored in the morning and then it will start sailing out to sea, and then it will be fishing for several hours, then it will come back and then it will moor again, so every few hours you expect a change in status. What if you wanted to report just the status changes, how d
o you do that given the fire hose? Because this is every message from every ship that's visible to the receivers. Saying when one particular ship has changed status is a little tricky. But we can do it because we've initially partitioned the stream of messages into a per-vessel group. This perShipObservables says I am going to omit one nested observable stream for each individual ship that I see. Then within that we're going to say, here is a stream of messages for one ship alone, I would like t
o just look at this message so give me the messages OfType this. Then I only want to see changes so that distinct until changed operator in Rx says if this thing emits a value but the value looks the same as the last one that I don't care I don't want to know I only want to see when it's changed. Basically, this says tell me every time this stream changes and you can pass in a call back to say what it is you're actually interested in so the speed might have changed that I care, the location mode
l changed I don't care I only care about the navigation state is changing. This is going to filter down that I've streamed with hundreds or thousands of messages the ship sends out down to just the ones where its navigation status changed. Remember this is all happening within the individual ship message stream. We have the firehouse we partition that into individual ships string then for each of those individual string I said, I'd like to watch each of those and see when something changes. That
's essentially the logic now doing a little bit more on here I say attitude, every time it changes states as I'd like to see its current status and its previous status so can you collect this in a sliding window of size 2 for each thing so every time it changes I'm going to see the current value and the previous value next to each other. When I count to actually print out a message I can say, what was the previous navigation status so looking at the first of the two messages what was this naviga
tion and then look at the second if it's a what was it's one. Then it select many actually flattens it will be straight back out again. Having done that per ship processing and filtering and saying, I'd like to chuck away all the messages except where something interesting happens. Can you then flatten that back down into one global stream of all the messages from all the ships? This is much lower volume in fact such low volume that none of the ships in the way of change status in the time I've
been talking I generally leave this running for about 20 minutes unless you run it at the times of day whenever ones leaving or entering the harbor so it does eventually start doing things but for me the interesting thing here is that we've taken a message source that produces thousands of messages a minute and a reduced it down to one that tells me just the things I'm interested in. This is a good example of the ability to combine global and local inspection because this distinct until change,
this is just looking at an individual ship because if I apply this across the whole fire hose it will tell me nothing useful. It would say, the status of this message is different from the status of the last message but that's a completely different ship so that tells me nothing that's all. I want to know when did this particular ship change its status that's what I care about and this is a technique in Rx known as fan out and fan back in again. I've got a linear stream all the messages. I fan t
hat out into a series of groups so it's like I've got not one stream at loads the strings, then I apply it processing on each of the streams within that fan, and then after I've done my processing I merge it back into one thing that contains this low volume but high-value event stream and annoyingly nothing still has changed if this is not a good time of day through this semi but eventually it. >> We will take your word for it, we believe you. >> Which is why I have the other demo because this o
ne at least is actually showing things, so this one I think the map's going to be quite busy now. It's definitely a real data source, there's definitely things happening here but they're all doing what they're doing either in Norway or spelled out apparently. That's all going on. There's a similar processing happening in this map 1. If we look at this one you'll see again I'm using group by MMSI. It's a basically take the single linear stream of all the messages from all the ships and fan those
out into a series of individual observables, one observable for each ship so it's a group observable because it's produced by GroupBy and then I can specify a stream of processing within that. This is slightly more complicated there's one that's rendering the map. It's having to combine several different types of messages. It says I want the navigation data that tells me where it is, where it's pointing, where it's heading, how fast is going. I also want them to the vessel name and actually I wa
nt to ship type as well. The color of the arrows is telling me something about whether it's a tanker or a ferry or a shipping vessel or something else. There's a whole bunch of different ship types so we're using that to color the map in. These three kinds of information here, and all three of those confront different message types it turns out. We're basically saying, from my per vessel stream that the GroupBy has given me, I filter out all three of these kinds of messages into three independen
t streams, so here all the location of speed changes, here are all the names, here are for this particular vessel and here is its report of ships. Then I combine that together with this Rx thing that says, I've got several streams here, I'd like to merge them back in so one where I get the latest value from each of the input streams. I combine later says whatever these five-three strings that don't give me the latest value from all three of them at any one time and then this ultimate is what fee
ds into populating the map. It's this ability to use the various filtering and partitioning and processing operators on your events that distinguishes Rx from regular Dotnet events. You really couldn't express this declaratively with ordinary Dotnet events and this compositional approach where you take lots of different small utilities like GroupBy, filtering, aggregation, windowing, and so on and you combine them in interesting ways to achieve the effect that you won't. That compositional style
is really the essence of Rx and it's the thing that takes the longest to get used to understanding how to combine the ingredients you have to produce the result you want is actually take some learning but once you get some familiarity with it it's ready powerful. >> I think you sparked a lot of interest here because our chat just started blowing up. There's many questions and people are looking for more resources if you have additional links that you can provide for further education after the
fact. Earlier on I did want to call attention to the fact that someone had mentioned this seems a lot like RxJS and there's a bit of irony there because this is the predecessor. >> It seems like RxJS because RxJS actually asked was a carbon copy of this, that's why they seem similar. >> There's a question about whether or not this is compatible with the CommunityToolkit.Mvvm. I would assume, so since it's.NET. >> Yeah. I mean, this is additive. It adds capabilities. If you're using.NET, you can
use this. I think the most subtle question is, is there any integration between this and whichever UI framework you are using? The answer to that is probably less so. It's not that you can't use MVVM. It's more than MVVM. It depends on which particular flavor you're using, but you might not necessarily have intrinsic integration. But what I would recommend is looking at ReactiveUX. Let's going to bring up a web browser here. >> ReactiveUI maybe. >> Sorry, ReactiveUI. >> Someone asked about that
specifically too. They said, what's the relationship between these two? >> ReactiveUI, this is not a thing I am directly involved in, but we consider them to be a really important customer of Rx. One of the things that we've been doing since we've taken over is trying to make sure that we are doing our best to address any issues that they have with the Rx codebase. We've done a few things that are specifically for them and anticipate doing more of that. What is ReactiveUI? ReactiveUI is a.NET fr
amework for doing user interface logic specifically with Rx. It is designed with Rx at its heart. If you want to do like MVVM with Rx, then ReactiveUI may be exactly the framework you are looking for, and I would strongly recommend going here and having a look at it because this does give you the power of those two concepts combines together. It's an amazing piece of light. There's a hole in here. It's really, really good, so yes. >> Awesome. Then Tom is asking about the IQbservable. >> IQbserva
ble is having announced. >> Perfect. >> How best to talk about this? >> That was a type, the Q there. >> Yes. People normally do. What is IQbservable? >> I just assumed that it was probably like the IQueryable where you basically in transmit near intense over the wire. >> That's pretty much yet, but let me show you for specifically what it is. I should probably quickly just actually introduced the code interfaces that are at the heart of Rx. I've just added the R, the System.Reactive library on
my project so I can tell you. For example, IQbservable long ticks equals observable. >> Well, to be clear, the IQbservable and IObserver interfaces aren't part of Rx.NET. Aren't they system? >> They are the heart of Rx. They're not part of System.Reactive though. They are the heart of Rx, but they all built into the.NET runtime libraries, so they are still the heart of Rx. >> Yes. >> It's just they happened to be able to build into the framework. Let me just quickly get an actual example so I ca
n show you something specific. This says I would like an IQbservable of type long, which I'm going to ask Rx, the Rx library, System.Reactive to build me one of those just by giving me a new tick every second, that if I just subscribe to this, WriteLine, this is absolute Hello World Rx. I've got an observable source and I've subscribed to it with an event handler that says what I want to do and I have to somehow make sure my process doesn't exit because it's all asynchronous. I'm just going to d
o a Console.ReadLine so keep things alive, and if I run this, this will start doing a tick every second. That's about as basic as it gets with Rx. I've said I've gotten observable sources raising event every second. What does this actually look like? IQbservable is pretty simple interface that has a single method called subscribe, which I called down here, except I actually called an extension method that helped me a bit. You subscribe to an IQbservable by providing an IObserver. How do you obse
rve? You have an observer. What this looks like is an interface with three methods: OnNext, OnError, and OnCompleted. The list in the least helpful order they could possibly be listed for you. OnNext is called every single time the source has a value for you. Each time you see that tick, that's because the observable source called OnNext or my observer. If something goes wrong, it's going to call on error, and if it has run out of things to give me and knows that nothing more, it calls on comple
ted to let me know that it's done. Not all sources do that observable, though interval would go on for as long as you care to remain subscribed to it. That's pretty much it. That's the whole of the basic programming model. Observables are things you can subscribe to and you have to supply an observer or some utility that implements IObserver for you, which is what I've done here. This just wraps my delegate in an IObserver interface and calls it. That's IQbservable. This is the basic. What about
IQbservable? Not a typo. Qbservable. You can basically write the same thing. What's the difference? Q on the answer that compiles. IQbservable looks pretty. I mean, it implements IQbservable, so it's very similar and it doesn't add a great deal more. We've got IQbservable inherits from IObservable, let's say. You can do anything with an IQbservable that you can do with an observable and then it also inherits from this known generic base interface, which will look familiar to anyone who's done a
ny IQueryable work in the world of link to data sources. The basic idea with this is that when you have an IQbservable, if I can find, actually sorry, this is this is not a great example. But the basic idea with this, sorry, I've realized I should have done something more complicated and we're going to run out of time if I do it. But the basic idea is that rather than actually building runnable code, it causes the C# compiler in general to emit query expressions. You may be familiar with doing t
his thing. If you say I'd like a function called ads, which let's call it d for double goes to x*2, that just generate some code. That just gives me a function that has the IL for that code baked into it. But if I wrap it in this, I get something completely different. I get a thing that describes the shape of this expression. If I let that run to there, what's happening? Yeah, didn't like my code because I forgot to do the thing that I didn't have time for. If we just let this run and hit that l
ine of code, what is d here? Well, d is actually a description of my expression. If I just zoom in a little bit on this so people got a chance of seeing it at home. It doesn't work very well in multi-modal systems listing the best. We can see it knows what the expression is. It says it's a Lambda that goes to x*2 and we can actually start to drill into this. If you drill down inside it, it will be a complete description. It says, hey, the body of this expression is actually a multiplication oper
ation, and the multiplication's left-hand operand is a parameter called x and its right-hand operand is a constant whose value is two. Essentially, rather than turning that into code, it's just built an object model that is a tree of objects describing what the expression looks like. Why is that interesting? That is interesting because it enables you to move the expression from one machine to another. There is a related project that we also maintain called Reaqtor, which is spelled Reaqtor with
q. If you want to find out about this, you should go to reaqtive.net, which is this site here, R-E-A-Q-T-I-V-E.NET, and this is essentially Rx in the Cloud. This is the way of hosting long-running subscription. If you want to have a thing that, for example, observes like a temperature sensor in some piece of industrial plants and that raises notifications when something goes out of range, you will not to keep running forever, for years at a time and you don't want it to shut down just because yo
u have to apply some updates to a device. Reaqtor built on top of Rx to say, well, we're going to need persistence. We need things to be able to be remembered. We need durability so if one machine goes down we can bring it back up again and have all the same state there as we had before. That's what Reaqtor does. But to be able to do this, it needs to know exactly what you're doing with Rx. Rather than you just having compiled IL, compiled code that represents what you did, it needs to see that
the description of what your query look like so that it can reconstitutes it if it has to reboot a server. Look, hang on a second, I have to show you this. Once I can move on to the screen, it was real. >> You got a message. >> I love that. You decide to leave it running to prove it. >> Yeah, I was laughing off on another screen a lot, so finally an interesting thing happened. >> So what's really interesting about Reaqtor and like the expression trees, and transferring the intent of your Rx. Jos
e was actually asking, how does Rx relate or work with Microsoft Orleans or Akka.NET. It sounds like Reaqtor are doing that to an extent. >> Well, how does it interact with those other frameworks? They're quite different programming models, so with Reaqtor you don't put any of your own code into the compute form that hosts Reaqtor. You just describe the queries you'd like it to run the subscriptions that you want, and then you tell it what the ingress and egress points are. You might say, I've g
ot like an Azure Event Hub here, I'd like to connect that in as the observable source for this query. Here's my query, and then please feed the results out through this Azure Event Grid, for example, or whatever it is you might want to do. The stuff that runs inside of Reaqtor is purely the Rx expressions. Like these queries I've been showing you, the group-bys, the filtering, all that stuff, that's what runs, and certainly you don't get to actually upload any of your code or tool into those thi
ngs, whereas things like Orleans and an Akka, it's much more of I deploy my code into this environment and then it provides me with a programming model that makes certain guarantees. They're only similar at quite a high level of distraction in the sense that they are well-defined models for managing long running computations on a server farm, but the actual mode of consumption is very, very different, I would say. I know there was some discussions between the Orleans group and the original creat
ors of Rx. I don't know if anything has come from that, they may or may not have plans for all I know about stuff there, but it'll be interesting to see what might happen, because you could easily imagine wanting to combine these two. The idea of having Reaqtor-style stream that then feeds into one of these other programming systems models, and then use those as a source downstream, that would be great. Today I'm unaware of anyone having done that with this. It's certainly technically possible,
but no one I know of has done the work, or if they have not been public with it. >> Very timely, Paul's asking about Reaqtor. He's like, is like is it like a durable task framework? >> It is a durable subscription framework. I think it actually persists. Let me go back to my previous example. Let's stop debugging, and let's load the lost example I did that actually worked, the push up status change one. The points at which you do a subscribe, so this thing down here, this is the point we're sayi
ng, okay, I've defined what my query is but now I actually want to subscribe to that and do something in response to it. That's actually the thing that gets captured by Reaqtor. You've actually subscribed to a thing, it doesn't really exist. It's like a tree falling in the forest. Until someone subscribes to listen to it, it doesn't actually happen, but it's actually a bit more real. The tree even fall over until you start listening to it. It takes that and slightly overstretches the reality of
it, but that's how it is. When you define an observable source like I've done here, nothing is actually happening yet. I've just said here is the definition of this observable that tells me about the shift status changes. This is all just an expression that says what to do, but it's only when I subscribe that anything actually begins to happen, because up until that point, there's know where for the data to go, so why would it do anything. Then Reaqtor with a key takes that a level further and s
ays, we will create a persistent thing at the point where you subscribe. It enhances this to things like identifiers, so a subscription actually has a URI associated with it, so you can go find it again later, if you need to. >> I'm just now realizing that we're approaching the top of the hour, and we haven't even talked really about modernizing very much. That was the emphasis of this episode, and we're going to definitely have to have you back on, because this is great. There's a lot of engage
ment, a lot of great questions. >> I'd like to talk very quickly about what we have done then, if I may. >> Absolutely. >> Please. >> Towards the end of last year, we approached the previous value of Rx because it had become more abandoned. Up until.NET 5, they'd managed to do a very good job of keeping releases going again and again, but for various reasons all people involved just didn't have the time to keep on that treadmill. We went in the space of only a year-and-a-half to Rx.net being app
arently completely up to date to people thought it was dead, because it hadn't had to release. It was particularly unfortunate that Rx 5 had the same version number is.NET 5, so everyone thought that when there was no Rx 6 that it had died. That wasn't actually true, but it was unhelpful s. Engines stepped in and they agree to let us to work on this thing, and so we became maintainers of the project, and we set out a roadmap for what we wanted to achieve. Back at the beginning of the year, we sa
id, here's our long-term vision, so here's all the various different flavors of.NET that we need to think about. There's. NET framework. There's.NET, there's Xamarin, there's UWP that's been supported in Rx forever and we're not about to remove support for that as Unity. We have to think like, what do all these different platform lifecycles look like, and then what do we have to do to accommodate that. We then said, here are a bunch of problems that we know about as well, so there have be no rel
eases for a while. The software didn't actually build if you opened it on current versions of the SDK and the tooling. There are certain problems that UI frameworks have been having with more recent versions of. NET, so it doesn't play well with trimming, it doesn't play well with ahead of time compilation. There was an ever-growing backlog of issues that was getting that [inaudible]. Also, there's a whole async variants of Rx that's been in an experimental state forever and hadn't been really.
We said, we're going to address these things over the next year, and so we said we're going to get a new release out. We are going to bring it up to date with current tooling. We're going to fix the [inaudible] problems. We're going to deal with the stalling at the backlog, and we're going to do async Rx a. We've achieved most of these. We did that. Rx 6 came out earlier this year. It builds properly on the current versions of everything. This is the one we haven't dealt with yet. This is a hard
one, making it avoiding code block problems on things like [inaudible]. We are making progress on this. There is still a big backlog of issues, but we do not respond to them. There is a preview version of async Rx now available on NuGet, so you can experiment with that if you want to, but it is a preview, not better, it's way before that. It's not ready for consumption yet, but you can go and look at it. We didn't go into more detail on that, but that's essentially what we've done. We've manage
d to achieve four of these five goals and it's not the end of the year yet, so we're hopeful we will actually manage to do all these things. Hence it opens requests about what to do in the longer term than that, but we wanted to get these things done because they were the ones most pressing for the community, so yeah, that's what's going on. >> Yeah, and it seems like the next pressing issue would be to have you guys just like own conference. Do it, Rx stuff. >> I'm not sure my boss would be up
for sponsoring that. I can ask him, but [inaudible]. >> You can come any time. You can come back and do more sessions and then we have a mini conference. >> There we go. >> Yeah, I can talk for days about this, as you probably already noticed. >> Awesome. One last thing I wanted to ask you really quick, in the beginning, you mentioned one of the things that your team was working on was improved education, can you talk about that really quickly? Because I'm sure folks, when they leave the field a
nd love to know, well, I want to learn the thing, where can I go and learn about some of the stuff that you guys are doing. >> This is unfortunately a work in progress, so we have this thing. There is the site Intro to Rx which she did link to earlier, but we haven't updated it yet. I opened it at a random chapter because I was working on it today. We are basically going through this. Actually, the content is not bad, it's just that little bit out of date, so it goes through all the parts of our
exit. Talks about the the core types I observe and are observable,. Talks about how to create observable sources. Talks about all the different ways you have of processing data, and then goes onto more pragmatic concerns like how you deal with threading? How you get back out into the outside non-Rx world. How do you handle errors? How do you do testing? Various things like that. There's a lot of information in here. We are probably still a couple of months off from actually having the updates o
ut there, I'm afraid, so it's not yet live. If you go there today you will find the very old content, but we are working on it and we want to get that out there as soon as we can, but I also have to do paying work from time-to-time, so it's going to be a little while. I'm also working on an update to my programming C Sharp book, so we're getting through this as fast as we can. >> You're a busy man. >> Yeah. >> Awesome. I think from the chat you can see that there was a lot of excitement. I think
a got the wheels on each person's brain spinning because people are thinking about how can they integrate into their projects, thinking about how can I use this so it's been awesome, so please come back at any point that you want to share more. I think we can do more demos with other [inaudible] people like to see. I want to thank you for coming here today, but also thank you everyone for watching and being such a great community, and asking questions, that's what makes the show shine. You can
go and check other great. NET live streams and videos at dot.net/live a. Tune in next week, we're going to have one of our host, Louis [inaudible], and he's going to be talking about opening an eye for. NET developers. Thanks for hanging out with us. If you want you can also submit your own talk like Ian did, and it would be awesome to have you on the show as well. Thank you, everyone, take care. >> Thanks you, bye. >> Thanks very much, bye. [MUSIC]

Comments

@osman3404

OMG. This is BEST talk on Rx I've seen in Loooong time, actually since the Ch9 Eric videos ;) PLEASE PLEASE, we need a regualr show for Ian Griffith dedicated to Rx. MS PLEASE make it happen

@kkleeberger

We have been using RX in many applications for years. Not only for UI but also for high performance data processing. The most underestimated technology. We love it. ❤

@AlexDresko

Been trying to understand Reactive since forever.. I'm hoping this rebirth makes that easier.

@andrewiecisa2907

Could you provide a link to repo of the demo?

@tauqirchaudhry2876

What is the capability provided by Rx. Is it same as SignalR

@JoseSilva-gt6zj

Talking about ReactiveUI at 40:00 .

@dmzone64

How does this work along MVVM community toolkit that also has observables?

@JoseSilva-gt6zj

Can we use RX-NET with Microsoft Orleans or AKKA-NET at 49:55 .