>> Hey, friends. Did you know that you can write
stateful functions in a serverless compute environment?
Durable Functions is an extension of Azure Functions,
it helps you to find stateful workflows.
David Justo is here to show me how that
works today on Azure Friday.
[MUSIC]
>> Hey, friends. I'm Scott Hanselman,
and it's Azure Friday.
I'm here with David Justo, who's going to show
me Durable Functions. How are you?
>> Pretty good, Scott. Thank you for
having me. How are you doing this Friday?
>> I'm living the dream.
I'm learning all about fun things on
Azure and that's always a good Friday.
>> All right. Yeah. I'm excited to tell you all
about bringing state back to the serverless space.
>> Is that a good thing or a bad thing?
Is this an architectural decision because I
know that we spent all this time trying to make things stateless,
because stateless things scale,
but sometimes business processes really need state.
It's easier to express,
it's easier to write.
Is that a good thing or bad thing?
>> Well, I would say that's a good thing,
I mean, you're right.
The serverless programming model has for
a long time being constrained to be
stateless precisely because it's good for scaling.
It just makes it easier if you're
a serverless provider to have things this way.
But at the end of the day, these are
constraints that we're talking about,
and so they make it difficult to implement
certain kinds of applications you would want to see.
Durable Functions makes that easier.
I guess now that we're on it,
how about I share my screen.
I'd love to just to get straight into it.
>> Let's do it. Let's see your demo.
>> Okay, let's see what's going on.
Actually, I wanted to start but I just establishing
some context, which you
actually already helped me get started with.
As you all know, if any of you has been in
the serverless space for any amount of time,
you would know that trying to incorporate state
into the serverless space is rather difficult.
The reason being that you have these constraints,
that your function should be
short-lived, and that they should be stateless.
Even though there's many applications
that fit this constraints rather well,
there's certain application patterns that
won't fit quite nicely into this model,
and so I want to give you an example, Scott.
Let's say that you want to implement a simple pipeline,
that you want to have a service on
the Cloud, that downloads a dataset,
run some function over it,
that processes that data set in some way.
So you calculate some statistic, and then
sends the result of that statistic to the user,
say, via an email.
You may try to fit all of these into
one serverless function just for convenience,
but you would quickly run into timing issues most likely,
because functions are supposed to be like quick, single-purpose.
So you'll probably find yourself having to split
it up into small different pieces,
maybe one per step,
say one function to download,
another function to process,
and another function to send the results.
This is when things started getting tricky and surprisingly,
because this is supposed to be a simple pipeline.
But in the serverless space,
since you don't have an easy way to communicate straightforward,
you're probably going to have to re-invent
certain programming constructs just like variable passing,
and variable passing you will probably take for
granted in most programming languages.
But in serverless, if you're
trying to pass variables across functions,
you probably have to coordinate with an external gear.
What Durable Functions does,
is it's going to give you
that stateful glue that's going to allow you to establish
these connections between functions that pass that data
around, and allow you to implement
these kinds of pipelines on the Cloud.
This is one kind of application
that Durable Functions can help you out with.
There's another one that I'm particularly excited about,
and that's something we call Fanning-out and Fanning-in.
You'll probably be familiar with this if you're familiar
with MapReduce style operations.
Going with the example,
let's say you have one starting function,
then download some data over the Internet,
and then per every data point in that dataset,
let's say you're running some transformation function
and you decide to do that in parallel,
because that's the whole thing about the Cloud.
This elastic scaling that you get on-demand.
You run those things in parallel,
and then you want to do that review step
where you aggregate the results back in.
For the same reasons as before,
doing this aggregation of results is
difficult in a serverless space because we
have no good way of determining when parallel work has concluded.
Yet again, Durable Function here is going to give
you the primitives and abstractions
that are going to allow you to complete that workflow,
if that makes sense, that's stateful workflow.
Just to emphasize the takeaways,
Durable Functions allows you to orchestrate
multiple purpose programs in
a serverless environment that can be long-lived,
potentially non-terminating,
and they do this by accessing persistent state.
The kinds of things this is going to enable
are pipelines like we talked about,
Fanning-out, Fanning-in, which is this MapReduce celebration,
and other things such as correlating external events,
monitoring long-running processes on the web,
implementing HTTP-based long-running APIs,
and implementing the kinds of services that allow
for human in the loop interruptions.
That's what Durable Functions is all about.
>> Interesting. Let me ask this though.
I could, as a programmer,
use regular Azure Functions and
the existing storage primitives that I have available to me,
whether they be queues, or tables, or
Cosmos DB as an external coordinator,
but I'm hearing you say that that's really not in the scope of
what my business person, or the person
who is in charge of me that asked me to write.
You're basically saying, work
on the thing that you need to work on.
We have primitives in
Azure Functions and Durable Functions that allow you to do this,
so that all that administer trivia of me trying to coordinate
external state and I'll probably get it wrong when I do it.
I don't have to think about that.
>> That's exactly right, Scott.
Like you said, the main idea is that
when trying to implement these kinds of things,
it is possible with standard serverless solutions,
but you will probably have to re-implement
certain programming primitives because
you're operating in a stateless environment.
>> Yeah.
>> Yeah. Exactly. Durable Functions is going to give
you a programmatic way of tying it all together.
>> Okay. Then that means
the kinds of things that I would do with regular code,
sharing state, passing variables,
try catches and things like that,
all of those kind of
lego pieces are available to me now with Durable Functions.
>> Exactly. In fact,
I'd love to show you an example just to get
these more concrete in our heads. How about that?
>> Please. Absolutely.
>> All right. I'm going to switch to Visual Studio Code,
and what I have right here is
that first simple pipeline we talked about.
What we're looking at here is what we
call an Orchestrator Function,
which is a Durable Functions concept,
but is essentially these stateful glue that ties
together serverless functions in Azure.
You can see here just at a high level
that we have as a first step,
these DownloadData step, that's going
to download some data, and we can get that
resulting to a standard Python variable, and pass it
around to the next step that's going to
count something in that data,
get those results back,
and pass that forward to these WriteMessage operation.
If this code looks simple, that's the point.
Because without it, you would probably
have to coordinate with registering
external cues, and just doing all sorts of declarative mumbo jumbo,
which here you can just express imperatively and programmatically.
>> I think imperative mumbo jumbo,
I think that's the correct technical term
for what you have to do because it is
a hassle, and having those primitives
in Durable Functions makes it a lot easier.
>> It does. In fact,
because this is a very a simple variable passing,
one of the things that
Durable Functions is particularly powerful in,
is scene recovering from exceptional outputs.
So x options. Let's say
that in this case as you can probably infer from the code,
we're downloading data of
the Wikipedia article for the Python programming language.
I'm going to switch to a slightly different version of this code.
I'm switching right here to slightly modify version of
that code that instead of trying to
download from the Python article,
it's trying to find an article for the language Sneaky Snake,
which obviously doesn't exist, but it probably should.
In that case, if we try to download data from that article,
we'll probably get a 404, and we'll probably get an exception back.
Trying to recover from exceptions in
standard serverless, it's a nightmare,
because now you have these extra layer
of coordination that you have to worry about,
and having to think about things like
retries gets hairy rather quickly.
In Durable Functions, you can just reuse
simple try, except blogs, to express
these recovery mechanisms in
the ways that you're already familiar with,
in the ways that programmers already are used to working in.
This is one of the things I'm particularly excited about.
>> How are you doing that? You're saying that you are taking
the language primitive that I'm used to
using, and extending it to the web itself.
>> That's the magic. That's right.
Yeah. The way we're doing it is,
some listeners that work in the .NET
environment might be familiar with the durable task framework.
>> Yeah.
>> Behind the curtain, we
actually hook up to the durable task frame,
but that's really where the name Durable Functions comes in.
We use that to help us orchestrate
these task parallel orchestrations
of code in a distributed fashion.
>> Interesting.
>> This just happens to be
the Python SDK that we've built on top of that.
>> Yeah, and that's a PyGitHub,
by the way, just as a side note for people.
People can go to Azure/durabletask, and they can read about
that task format, and they can basically
learn that in C#, and apply it to other things as well so,
just as a little aside.
>> Right. I'd love to get this running just in the right.
Just so I can prove that this is not just static code.
If I may, what I'm going to do right now is I'm going
to expand my terminal,
and start the Azure Functions local server with func host start.
When we do that,
we're going to get these handy listing
of these other functions that have been declared.
You'll see right here that we've created
this HTTP endpoint that we can hit,
and specify an orchestrator name to pick start our orchestration.
Here, the orchestrations we've defined happen to be
the simple sequential orchestrator that I talked
about first in the error handling one.
Just to show how a simple hello world example would look like,
switching to post man.
Before I move forward, is this readable, Scott?
Should I make this any bigger for the viewers?
>> No, I think that looks great, thank you.
>> Perfect. Here I have essentially that now parameterized URL,
and I'm going to hit it with a "Send".
What I'm going to get back is
these JSON of URLs that are going to allow
us to interact with
these orchestrator functions in a variety of ways.
But right now, for example purposes,
let's just focus on the statusQueryGetUri1,
which is going to give us
just a general overview of the status of that orchestration.
I'm going to click on that, I'm going to send
that request, and our result we get, hey,
this orchestration has completed, and
its output was that you've found a total
of 1,446 lines in
that Wikipedia article on the Python programming language.
Similarly, let me close this one,
if you wanted to see the result for
the error handling orchestrator that I showed,
we can hit it, go to that same statusUri,
get that request as well and we see, hey,
it's completed and in fact,
you could not find the article requested.
Just a few lines of code,
we can express these pipelines,
and we can express these pipelines by
including error recovery as well.
>> It's very clean.
>> It is clean and is simple.
It doesn't take that much time to pick up on.
The last thing, Scott, I wanted to show you was
this elastic parallelization pattern
that I talked about, fan out, fan in.
>> Yeah.
>> Here's what we're going to do, it's going to be a bit of
more of a realistic application.
>> All right.
>> What I have right here is a website that has been deployed on
Azure, and it's back
and it's going to be powered by Durable Functions.
What this website is going to do,
is it's going to download a given number
of images of the Internet of either dogs or cats,
and using Durable Functions,
it's going to in parallel load items
for flow model, and try to
predict whether or not it's a cat or a dog.
As those results start coming in,
what you're going to see on the website,
to our predictions start populate the page.
Now before I click on that classify images button,
I just want to highlight the code.
I'm going to go to VS Code again,
and just a high-level breakdown of what we're looking at here.
Number 1, as you see this is an orchestrator function.
As you see, orchestrators can get input dynamically.
What we're doing first is,
we're downloading pictures of the Internet to classify,
then, and this is the important bit,
we're creating an array of tasks that we are populating
for every image that we
downloaded with a task to classify that image.
Instead of calling yield on every one of those tasks,
we're going to use these Durable Functions
API called task o that's going to say,
"Hey, for everything in that array of tasks,
do it in parallel,
and give me all the results back."
This is how we can get to
express those MapReduce style operations.
With all that being said, I'm going to switch back.
Let's say we want to classify 100 images and let's watch it roll.
The first thing we're going to do is, go to the Internet,
we're going to download a bunch of images,
that may take a second,
and then you're going to start to see
the pictures and our predictions populate the page and hopefully,
you'll see that's elastic scaling start taking place
as the speed of
our results are like accelerates as Azure realizes that,
oh, the demand is increasing,
let me give you more workers to work on.
At any given point in time,
this could be running on hundreds of nodes,
and you could classify all your cats and
dogs next time you're confused,
Azure Durable Functions got your back.
>> It sounds like it could actually probably go
faster than the browser can handle there,
even from a half of a cat a second to five,
six, ten and going faster and faster.
You can go faster than your browser can handle that.
>> You could probably go faster, that's right.
>> That's amazing.
>> Yeah, absolutely.
These are the things that would normally take quite a bit
of overhead to orchestrating the serverless space,
and now it's a little bit
easier, and that's what I'm excited about it.
>> That's great. What I like about this is that it layers
just so cleanly on top of Azure Functions,
so people who are familiar with basic Azure Functions or
basic serverless concepts, it's very comfortable.
It layers on top very cleanly,
I like that you're not making us learn any new primitives,
if you know how to do exception handling, if you know how to do.
I mean, that was a pretty naive for loop, and you've fanned
out very nicely to categorize all of our dogs and cats.
>> That's right. Right now,
we're talking about Azure Durable Functions for Python,
but as it turns out we also have bindings for
JavaScript and C Sharp
for these Durable Functions programming model,
and hopefully, in the future we will see it
in more and more offerings.
I would love to see it in
a more niche language as well, like Haskell,
or just something people wouldn't normally
expect to keep an eye out for that as well.
>> Very cool, go ahead, and
make sure that you check out the show notes.
We'll have links to Durable Functions for .NET,
for Python, for JavaScript,
as well as the overview.
I'm learning all about
Azure Durable Functions today on Azure Friday.
Hey, thanks for watching this episode of
Azure Friday, now I need you to like it,
comment on it, tell your friends,
retweet it, watch more Azure Friday.
[MUSIC]