Let's face it, our world will be taken over by robots, or at least our jobs as the scary ML & AI speculations seem to say. But until that day arrives, I want to take you on a hypothetical journey of designing and creating a fully automated restaurant of the future, where a fine tuned and efficiently orchestrated group of RoboChefs will cook your desired meal perfectly each time. And all of this is possible thanks to Actions, Timers, Monitors, Orchestrators, Sub-Orchestrators and more, all concepts from Azure Durable Functions, the real focus of this session, an extension to Functions that adds state, and which are part of Azure's Serverless Compute technologies.
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
RoboRestaurant of the future powered by serverless technologies
1. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
RoboRestaurant of the future
powered by serverless technologies
of today
Emil Crăciun
Software Development Engineer in Test / Lateral Inc. / emilcraciun.net
3. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
{
“FullName”: “Emil Crăciun”,
“Company”: “Lateral Inc.”,
“Position”: “Software Development Engineer in Test”,
“Traits”: [“dev”, “Azure”, “teaching”, “speaking” “quality”,
“security”, “passionate”],
“Blog”: “emilcraciun.net”,
“Other”: “playing with fire 🔥🔥🔥”
}
Who am I?
4. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
• Solution motivation, overview and showcase
• Serverless concepts review
• A journey through the technical implementation
– Key concepts
– Tips & tricks
– Watch out!
• Conclusions & summary
• Resources
• Q&A
Agenda outline
6. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Here’s a naïve vision of the “business”
Main aspects:
1. Everything starting from an order to a happy belly
2. Having enough stuff to … stuff them bellies!
3. Personnel management (oh right, they are robots)
(I probably shouldn’t start my own restaurant…yet)
7. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
A Order flow
New order
Validate order
and start
Order
ingredients
and wait
Prepare order
Enough
ingredients?
Deliver order
Yes
No
8. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
B Stock checking flow
Start
Get all stock
quantities
Any low
ones?
Place restock
orders and
wait
Update stock
quantities
Sleep
Yes
No
11. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
The “serverless” buzzword
But moooom, do I
really have to take
care of the
infrastructure too? No honey, you just give
them your money and
they’ll take care of the
rest
12. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
“Assumptions are the mother of all f***-ups”
- a person smarter than me
Azure Functions…but you already know this
14. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
CosmosDB
Restaurant
Client API
Backoffice API
Static
website
Common Storage
Account &
Application Insights
Azure Functions…but you already know this
15. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
LET ME SHOW YOU WHAT I MEAN
FYI: It’s not going to be pretty, but bear with me, you’ll get the point
16. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
A Order flow (remembering)
New order
Validate order
and start
Order
ingredients
and wait
Prepare order
Enough
ingredients?
Deliver order
Yes
No
17. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
A1 Order Orchestrator
Order
Mark order
as in
progress
Get all dishes
to prepare
Get list of
required
ingredients and
quantities
Check and
reserve
ingredients
Prepare
dishes
Mark order
as ready
End
A2 A3
18. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Client function -> Orchestrator function -> Activity
function
Client = starter
Orchestrator = well, it’s pretty self-explanatory
Activity = unit of work / heavy lifter
Main durable orchestration flow
19. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Logical container for Azure Storage resources that are
used for orchestrations
Contains:
• One or more control queues.
• One work-item queue.
• One history table.
• One instances table.
• One storage container containing one or more lease
blobs.
Task hubs
20. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Orchestrator functions are replayed using the contents
of the History table. By default, the orchestrator
function code is replayed every time a batch of
messages are dequeued from a control queue.
Orchestrator replay
21. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
A2 Stock Checker Orchestrator
Needed
ingredients
and quantities
Check and
reserve stock
Anything
missing?
End
Get fastest
suppliers
Create
supplier
orders and
wait for them
Update
ingredient
quantities in
stock
Get current
stock
quantities
Check and
reserve stock
Yes
No
24. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Firstly, inject the base version of anything you need.
Then mock what you call.
Finally, create your test cases.
Testing durable functions
25. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
B Stock checking flow (remembering)
Start
Get all stock
quantities
Any low
ones?
Place restock
orders and
wait
Update stock
quantities
Sleep
Yes
No
26. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
B1 Inventory Checker Eternal Orchestrator
Start
Get current
stock
quantities Get cheapest
suppliers
Create
supplier
orders
Anything
low?
Sleep
No
Yes
Start orders
monitor
B2
27. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Orchestrator code must be
deterministic
non-blocking
never initiate async except using the
DurableOrchestrationContext
avoid infinite loops
Reliable execution
28. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
We mustn’t go all random …
Since the code must be deterministic…
- Need a new GUID ->
DurableOrchestrationContextBase.NewGuid()
- Need current DateTime ->
DurableOrchestrationContextBase.CurrentUtcDateTime
29. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
B2 Supplier Order Monitor Orchestrator
Orders to
watch
End
Set
timeout
Timeout
reached?
Still
pending?
Get supplier
orders
Send
completed
order events
to B3
Sleep
No
NoYes
Yes
30. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
B3 Supplier Order Receiver Orchestrator
Start
Wait for order
event
Update
ingredient
quantities in
stock
Update order
as picked up
31. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
• Waiting for external events
• Singleton
• Eternal
• Timer
Patterns used in the stock checking flow
32. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Consider counting your chickens…I mean functions
Orchestrator functions are executed on a single thread
to ensure that execution can be deterministic across
many replays.
Azure Functions supports executing multiple functions
concurrently within a single app instance.
The default number of concurrent activity and
orchestrator function executions is capped at 10X the
number of cores on the VM.
33. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Cost considerations
Each execution = $
Orchestrators replay several times until completing.
Replay = execution = $
Several short executions are cheaper than a longer one.
The duration of an await (activity, wait for event, timer) = free
34. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Keep in mind functions start out cold
From when an event happens to start up a function until
that function completes responding to the event.
Happens on a consumption plan.
36. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Key takeaways
Serverless lets us focus on the what not how, where,
etc.
Durable Functions (DF) are great for setting up
workflows in code up in the cloud.
There are 3 types of functions involved: client,
orchestrator and activity.
37. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Key takeaways
Orchestrators get replayed so they need to be
deterministic.
Testing the 3 types of functions is pretty straightforward.
Behind the scenes DF implement CQRS & ES patterns
using history tables, work item and control queues.
38. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Key takeaways
There are several patterns from which I used:
- Function chaining
- Fan out/Fan in
- Sub-orchestrations
- Durable timers
- External events
- Eternal & singleton orchestrators
39. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
And never forget…
“Cloud doesn’t fix stupidity”
- another person smarter than me
Translation: research, study, try out, ask, test, test, test,
test!
41. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Resources
AF: https://bit.ly/2kuo9Bb
ADB: https://bit.ly/30YDhZV , https://bit.ly/2Kj81z1,
https://bit.ly/2Z12bWT
Serverless comparison: https://bit.ly/2XiNLBa
CosmosDB: https://bit.ly/2r49cGy
CosmosDB SQL API samples: https://bit.ly/30ZlC4m
DI in AF: https://bit.ly/2Ia0Zd7 , https://bit.ly/2wyOFxu
Cold starts: https://bit.ly/2XjG6m1 ,
https://bit.ly/2MBFUxR
42. @ITCAMPRO #ITCAMP19Community Conference for IT Professionals
Resources
Keep an eye on what’s coming up next:
https://docs.microsoft.com/en-us/azure/azure-
functions/durable/durable-functions-preview
And I almost forgot, the code can be found here:
https://github.com/ecraciun/ServerlessRoboRestaurant
Serverless computing (or serverless for short), is an execution model where the cloud provider is responsible for executing a piece of code by dynamically allocating the resources. And only charging for the amount of resources used to run the code. The code is typically run inside stateless containers that can be triggered by a variety of events including http requests, database events, queuing services, monitoring alerts, file uploads, scheduled events (cron jobs), etc. The code that is sent to the cloud provider for execution is usually in the form of a function. Hence serverless is sometimes referred to as “Functions as a Service” or “FaaS”.
While serverless abstracts the underlying infrastructure away from the developer, servers are still involved in executing our functions.
Benefits: see word doc
Azure Functions is a solution for easily running small pieces of code, or "functions," in the cloud. You can write just the code you need for the problem at hand, without worrying about a whole application or the infrastructure to run it. Functions can make development even more productive, and you can use your development language of choice, such as C#, F#, Node.js, Java, or PHP. Pay only for the time your code runs and trust Azure to scale as needed.
Durable Functions are an extension of Azure Functions that lets you write stateful functions in a serverless environment. The extension manages state, checkpoints, and restarts for you.
The extension lets you define stateful workflows using an orchestrator function, which can provide the following benefits:
You can define your workflows in code.
No JSON schemas or designers are needed.
Other functions can be called both synchronously and asynchronously. Output from called functions can be saved to local variables.
Progress is automatically checkpointed when the function awaits. Local state is never lost when the process recycles or the VM reboots.
Application patterns
Durable Functions currently supports the following languages:
C#: both precompiled class libraries and C# script.
F#: precompiled class libraries and F# script. F# script is only supported for version 1.x of the Azure Functions runtime.
JavaScript: supported only for version 2.x of the Azure Functions runtime. Requires version 1.7.0 of the Durable Functions extension, or a later version.
Azure Functions pricing
Azure Functions consumption plan is billed based on per-second resource consumption and executions.
A task hub in Durable Functions is a logical container for Azure Storage resources that are used for orchestrations. Orchestrator and activity functions can only interact with each other when they belong to the same task hub.
If multiple function apps share a storage account, each function app must be configured with a separate task hub name. A storage account can contain multiple task hubs. The following diagram illustrates one task hub per function app in shared and dedicated storage accounts.
Orchestrator function replay
As mentioned previously, orchestrator functions are replayed using the contents of the History table. By default, the orchestrator function code is replayed every time a batch of messages are dequeued from a control queue.
This aggressive replay behavior can be disabled by enabling extended sessions. When extended sessions are enabled, orchestrator function instances are held in memory longer and new messages can be processed without a full replay. Extended sessions are enabled by setting durableTask/extendedSessionsEnabled to true in the host.json file. The durableTask/extendedSessionIdleTimeoutInSeconds setting is used to control how long an idle session will be held in memory:
The typical effect of enabling extended sessions is reduced I/O against the Azure Storage account and overall improved throughput.
However, one potential downside of this feature is that idle orchestrator function instances will stay in memory longer. There are two effects to be aware of:
Overall increase in function app memory usage.
Overall decrease in throughput if there are many concurrent, short-lived orchestrator function executions.
Thread usage
Orchestrator functions are executed on a single thread to ensure that execution can be deterministic across many replays. Because of this single-threaded execution, it's important that orchestrator function threads do not perform CPU-intensive tasks, do I/O, or block for any reason. Any work that may require I/O, blocking, or multiple threads should be moved into activity functions.
Activity functions have all the same behaviors as regular queue-triggered functions. They can safely do I/O, execute CPU intensive operations, and use multiple threads. Because activity triggers are stateless, they can freely scale out to an unbounded number of VMs.
Concurrency throttles
Azure Functions supports executing multiple functions concurrently within a single app instance. This concurrent execution helps increase parallelism and minimizes the number of "cold starts" that a typical app will experience over time. However, high concurrency can result in high per-VM memory usage. Depending on the needs of the function app, it may be necessary to throttle the per-instance concurrency to avoid the possibility of running out of memory in high-load situations.
Both activity function and orchestrator function concurrency limits can be configured in the host.json file. The relevant settings are durableTask/maxConcurrentActivityFunctions and durableTask/maxConcurrentOrchestratorFunctions respectively.
In the previous example, a maximum of 10 orchestrator functions and 10 activity functions can run on a single VM concurrently. If not specified, the number of concurrent activity and orchestrator function executions is capped at 10X the number of cores on the VM.
Since your functions are run inside a container that is brought up on demand to respond to an event, there is some latency associated with it. This is referred to as a Cold Start. Your container might be kept around for a little while after your function has completed execution. If another event is triggered during this time it responds far more quickly and this is typically known as a Warm Start.
The duration of cold starts depends on the implementation of the specific cloud provider. On AWS Lambda it can range from anywhere between a few hundred milliseconds to a few seconds. It can depend on the runtime (or language) used, the size of the function (as a package), and of course the cloud provider in question. Cold starts have drastically improved over the years as cloud providers have gotten much better at optimizing for lower latency times.
Aside from optimizing your functions, you can use simple tricks like a separate scheduled function to invoke your function every few minutes to keep it warm.