My Authors
Read all threads
Recently @stimms asked about comparisons between Azure Durable Functions and NServiceBus sagas.
First of all, for anyone curious about what Azure Functions and Durable Functions are all about, this article by @MikhailShilkov (which we also recently tweeted) is a pretty good primer, and in line with how we normally teach SOA: hackernoon.com/making-sense-o…
(And for anyone curious about what NServiceBus sagas are, check out our saga tutorial: docs.particular.net/tutorials/nser… )
Before continuing, a quick disclaimer: Durable Functions are extremely new. We haven't fully assessed them yet. This is just a few engineers throwing thoughts against the wall. Our position is guaranteed to evolve over time. Now, on with the show…
There's definitely some similarities between durable functions and sagas. After all, an NServiceBus saga is essentially an NServiceBus message handler with durable state, and a durable function is an Azure Function with durable state.
One big difference is that a durable function is a non-message-bound orchestrator for other functions or processes. That means continuation of the durable function is driven by awaits, not by additional messages.
A very cool part about durable functions is that they automatically checkpoint their progress whenever the function awaits. Local state is never lost if the process recycles or the VM reboots.
But this behavior is not free and does have consequences! The orchestrator stores the history of its past executions in Azure Storage, then executes the ENTIRE function again from the BEGINNING, skipping awaits already finished in previous runs.
So with durable functions you need to be careful that your orchestrator's implementation is deterministic. DateTime.Now, random numbers, Guids, etc. will get you into trouble! docs.microsoft.com/en-us/azure/az…
A Saga will typically focus on the interaction of one or two messages at a time. When thinking about a large process flowchart, one Saga will typically govern just the interactions at one point on the flowchart, not the entire process.
On the other hand, with a durable function, it's easy to have an entire process represented as one durable orchestrator function that can call other functions. This is both a strength (easily seeing the big picture) and a weakness (lots of coupling, can grow very complex).
Additionally, if you're trying to divide your system along service boundary lines (the vertical slices with independent databases mentioned in @MikhailShilkov's article) a giant orchestrator function covering an entire process flowchart makes this really difficult.
A Saga on the other hand is a kind of "policy" object which statefully handles a few interrelated messages. It is completely isolated in its own vertical slice, and can communicate with other vertical slices in a lightly-coupled manner by publishing events.
The dangers of an all-encompassing durable function could be mitigated somewhat by doing all the real work in normal azure functions which are called from the orchestrator, and having the durable function be very lightweight, but this is a bit of a slipperly slope.
Speaking of calling other functions, to do that you use the DurableOrchestrationContext's `CallActivityAsync<TResult>("FunctionName")`. This requires the use of "magic strings" for the function names, definitely not refactoring-friendly. docs.microsoft.com/en-us/azure/az…
The capabilities of durable functions are impressive, but with an orchestrator function spanning multiple service boundaries and calling multiple other functions identified by magic strings in a command/control style, it would be VERY easy to end up with a distributed monolith.
Also, chaining functions together is itself a form of coupling, and this raises versioning challenges when changes to a system need to be made. docs.microsoft.com/en-us/azure/az…
In NServiceBus a Saga is a stateful object with some Handle(message) methods on it where that state is persisted to a database. Even timeouts are represented as messages.
The messages are strongly-typed classes. No magic strings. Message comes in, stored state is read, make some decisions, message(s) come out. Easy to test, easy to refactor. docs.particular.net/nservicebus/te…
And if anything goes wrong, the message rolls back to the queue and automatic retries kick in. This makes it easy for your system to recover from transient outages of databases or 3rd party APIs: docs.particular.net/tutorials/quic…
Also, when reproducing a bug in your system, having the actual messages which caused the failure in an error queue is a huge help, not to mention being able to "replay" them in production to complete the business process for your customer: docs.particular.net/tutorials/mess…
Of course, this wouldn't be complete without our real-time performance monitoring capabilities. Keep an eye on message processing time, retries, and queues backing up - resolving issues before they hurt the business: particular.net/real-time-moni…
But it's naïve to think that a system would have to be ALL sagas or ALL durable functions. Don't fall for the golden hammer fallacy, use each where it makes sense!
Azure Functions can be really great integration glue to bridge from various Azure Services like Blobs, Tables, Event Grid, CosmosDB, etc. to NServiceBus sagas and from there to your core business logic.
Azure functions are also great for small bits of infrastructure - we even recommend using them with NServiceBus to clean up data bus entries: docs.particular.net/samples/azure/…
No matter what, remember that Azure Durable Functions are in their infancy. Going "all in" may not be the best bet. Start small.
Also keep "credit-card-driven development" in mind. Azure Functions billing is all about actual usage. @troyhunt runs the haveibeenpwned API for pennies because the function is ridiculously efficient. You have to design for that, or you might get a bill you didn't expect.
We’re still assessing Azure Functions, so if you are actively using them in production or even thinking about using them some day, we’d love to get your input! Leave your comments here: discuss.particular.net/t/azure-functi…
Missing some Tweet in this thread? You can try to force a refresh.

Enjoying this thread?

Keep Current with Particular Software

Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Follow Us on Twitter!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!