[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
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
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. ❤
Been trying to understand Reactive since forever.. I'm hoping this rebirth makes that easier.
Could you provide a link to repo of the demo?
What is the capability provided by Rx. Is it same as SignalR
Talking about ReactiveUI at 40:00 .
How does this work along MVVM community toolkit that also has observables?
Can we use RX-NET with Microsoft Orleans or AKKA-NET at 49:55 .
Nice