S06E19 1h 11mSeason 6

Episode Summary
In the world of modern software development, the need for reliable and efficient distributed systems is paramount. With the rise of cloud computing and the increasing complexity of applications, developers are constantly seeking tools and frameworks that can simplify the creation of robust and scalable systems. One such tool that has been gaining popularity in the .NET community is Temporal.
Temporal is a new SDK for .NET that focuses on durable execution, ensuring that code runs to completion despite transient failures in distributed systems. It manages workflows and activities, such as calling external APIs or services, and handles recovery and consistency issues automatically. This approach to handling distributed systems has made Temporal a favourite among companies like Snapchat, Airbnb, and Stripe, as well as in the finance industry for guaranteeing transaction completion.
What sets Temporal apart is its versatility and ease of use. The founders of Temporal, who previously worked at Microsoft and Uber, have created a platform that supports multiple SDKs, including .NET, Python, TypeScript, PHP, and Go. This makes it appealing for organizations with diverse technology stacks, as it allows teams using different languages to seamlessly collaborate within the Temporal ecosystem.
One of the key benefits of Temporal is its focus on security. By encrypting keys and ensuring that data is not exposed to the server or any observers, Temporal provides a level of data protection that is crucial for industries with strict security requirements. This focus on security, combined with its robust capabilities for handling idempotent activities, results in more efficient and maintainable codebases for developers.
Temporal simplifies the development of reliable distributed systems by abstracting away the complexity of managing workflows and activities. By leveraging Temporal’s capabilities, developers can focus on the business logic of their applications rather than worrying about the underlying plumbing of distributed systems. This leads to a more streamlined development process and reduces the risk of errors in complex distributed environments.
In conclusion, Temporal is a powerful tool for building reliable and efficient distributed systems in the .NET ecosystem. With its focus on durability, security, and ease of use, Temporal is a valuable addition to any developer’s toolkit. Whether you are working on a small app or a large enterprise system, Temporal’s capabilities for managing workflows and activities make it a versatile and indispensable tool for modern software development.
Episode Transcription
When you talk to the Temporal guys and look at the way that they’ve done some of their work is they have a… they have stuff that can run for years.
So for instance, they’ll kick off a workflow for one of their customers, kicks off a workflow when the customer’s created, and that workflow is like managed by Temporal for as long as that customer is a customer. So it could be, you know, I don’t know, occasionally sending out an email to, you know, "happy birthday" or something, or sending them promotions or whatever. So they see, they see workflows as like lifetime things
Welcome to The Modern .NET Show! Formerly known as The .NET Core Podcast, we are the go-to podcast for all .NET developers worldwide and I am your host Jamie “GaProgMan” Taylor.
In this episode, John Kattenhorn joined us to talk about Temporal.io and their platform for building durable workflows which can operate for years at a time. John in the CEO of Applicita and wanted to talk about the ways that developers can build applications and workflows which can live in the cloud for a very long time.
And the great thing about Temporal is it manages all of those resources for you.
So if you imagined me and you trying to do that, we’d end up standing up, I don’t know, a running service or something that was constantly polling the data, looking for eligible customers or something. You’d be burning some resources looking at that stuff, and that’s not how they do that. So if you’ve got like a million customers, the Temporal system dehydrates everything that isn’t relevant and only hydrates the workflows that have an action to perform.
So let’s sit back, open up a terminal, type in dotnet new podcast and we’ll dive into the core of Modern .NET.
Jamie
John
Jamie
So yeah, we’ll get on to, I mean, people have been listening so far. They’ve seen the name of the, the episode topic. So we’ll. And you’ve just said it as well, we’re going to talk about Temporal and some durable stuff.
John
Jamie
John
Jamie
John
So yeah, what the problem that Temporal solves is around what they call durable execution. And that really means about running code to completion no matter what transient failures or anything like that, which is often some of the issues you have in distributed systems. You’ve got maybe third party APIs, you’ve got other bits of your own system that can’t always be there or, you know, you’ve got a big system, you want to be able to take bits of it down, but some of it’s still sort of functional.
So they, Temporal, tend to sort of view this as like workflow, workflow and activities. So effectively what they’re, their durable execution system is doing is executing workflow. And within those workflows, you’ve got various activities. So, you know, a good example of activity might be calling an external API or perhaps calling another service that you’ve got internally. And what it does is it’s actually marshalling and managing how the workflow is working and restarting if there’s been failures at the correct place.
So fundamentally, it’s doing a lot of the work that you can obviously do in .NET yourself. I mean, there’s some great libraries around that help with some transient failures like Polly and a few other things, but this kind of goes way beyond that. It’s used, for instance, for Snapchat, use it, airbnb, use it, stripe, use it. It’s used a lot in finance to sort of guarantee the completion of transactions and stuff like that. So Temporal now finally supports .NET, which is kind of what peaked our interest.
Jamie
John
Jamie
John
Temporal, takes a lot of that pain. So basically, you, you hand control of the status of, you know, where you are in that workflow to Temporal, and Temporal will manage for you how to recover. So it will know which sort of activities have completed. So, you know, did the strike payment go through? Did the, did the inventory, was the inventory actually available? You know, all that kind of stuff. And you can basically then focus on the "what" of the activity, not necessarily the sort of worrying about the plumbing of, you know, making sure that you can do recovery and make sure that things are consistent. So that’s really what Temporal is there to do.
One of the things that’s really cool about it that I found interesting in their approach was that there are some other systems around that do something similar to Temporal, but it effectively ships data to a central cloud service. And if you’re in an organization that has some security concerns or is handling sensitive data, you can’t, you can’t really do that. You can’t really use those. You can’t ship off, I don’t know, people’s account details into some unknown third party system. Like your security people won’t allow that. So the way that Temporal gets around this problem is that they actually, you install the "workers," as they call it, in your environment. So that could be on the cloud. If your company’s company got private cloud or something, it could equally be on a bunch of VMs or whatever, and then it’s receiving its instructions to do things from the Temporal server itself, which is either hosted again yourself. It’s entirely open source. So you could literally run the whole Temporal environment yourself if you wanted to. Or they provide like a SaaS cloud environment that allows the workers to be sort of marshalled by the cloud system. But the great thing is you’re not shipping any data. At worst, you’re shipping keys, primary keys or external ID keys. And then even then, they have a way of encrypting those so that they can’t see them, and neither can anybody else is observing the server. So they thought hard about how to do that in a more secure environment, which I guess is another reason why it gets picked up a lot in finance and that kind of stuff.
Jamie
John
Jamie
John
So it’s not, it’s not anything to do with Temporal. It’s just about building reliable distributed systems. Right. That you have to be able to architectural system in a way where you can make calls to something, you know, more than once and it’s state change only changes on the first time, you know, so there’s no side effect of calling that thing, you know, multiple times. So you have to bear that in mind in terms of like, distributed systems and like, building distributed systems and stuff. And there’s plenty of, plenty of techniques for doing that, but once you get your, you know, your teams and your people’s heads around how to do that, then it becomes really easy. I mean, some of the code that we’ve, we’ve done some comparisons between code we’ve written ourselves to do the things that Temporal do and then, you know, a Temporal solution and your code base like shrinks like crazy. It’s, it’s really probably, we reckon about 35% of the code that we wrote was just like glue for making these things like, you know, act properly. And they’re still probably not doing the complete job that Temporal is doing, but, you know, with none of the code, which is like super good. Right?
Jamie
John
Jamie
John
Jamie
And you know, that makes perfect sense, right. Because like you said, you’re, if you’re in a team where you’re using, shall we say, the best tool for the job. And, you know, I’m very aware of the, the show that I produce, but .NET isn’t always the best tool for the job. Right? The same, that same way that, like, TypeScript isn’t always the best tool for the job. Yeah, Python isn’t always the best tool for the job or even Go isn’t the best tool for the job all the time. Right?
If I’m going to write, for instance, a, a video game that is going to target, like, home video game consoles, all right, I may use the Godot or GoDot IDE, but I may not be actually writing go itself. Whereas I might want to be using Unity or Unreal or any of those big ones and some of those have.NET stuff in them. And if I’m doing machine learning stuff, maybe I’m doing some actual building the machine learning stuff rather than using an API that Python’s probably the best way to go. So I really like the idea that there are multiple different language, how do I put it? So it sounds like there’s an SDK for a bunch of languages, but itself is not SDK specific. It’s like agnostic to, I said SDK languages, but you know what I mean? You know what I mean, right?
John
The other couple of cool things, and it takes you a little while to get your head around this. And again, this isn’t necessarily a Temporal thing, although they highlighted to us is your workflows. We as .NET developers typically think about workflows as being fairly short lived things. It could be, to your example, it could be like e-commerce transaction or something, where you’ve got to do a bunch of things fairly quickly, you’ve got to move some inventory, you’ve got to take a payment, credit card or whatever. When you talk to the Temporal guys and look at the way that they’ve done some of their work is they have stuff that can run for years. So for instance, they’ll kick off a workflow for one of their customers, kicks off a workflow when the customer’s created, and that workflow is like managed by Temporal for as long as that customer is a customer. So it could be, you know, I don’t know, occasionally sending out an email to, you know, "happy birthday" or something, or sending them promotions or whatever. So they see, they see workflows as like lifetime things.
And the great thing about Temporal is it manages all of those resources for you. So if you imagined me and you trying to do that, we’d end up standing up, I don’t know, a running service or something that was constantly polling the data, looking for eligible customers or something. You’d be burning some resources looking at that stuff, and that’s not how they do that. So if you’ve got like a million customers, the Temporal system dehydrates everything that isn’t relevant and only hydrates the workflows that have an action to perform. So you end up with this sort of super compressed sort of situation where you’ve got like really high density, you know, you could have like millions of workflows, but they’re not, they’re not actually active at the moment, so they’re not consuming resources.
And that’s quite difficult to do yourself in the .NET world, I think you already know, but we’re big Orleans users and all things has something in it which does something. It’s in some respects a durable execution framework or platform rather than a framework. It just doesn’t have any of the semantics of Temporal. But you could definitely build a, you know, a Temporal-like system on top of all liens if you wanted to. And that also has a, you know, way of expiring kind of, you know, grains, as they call them, which are effectively actors and, you know, put them to sleep until they, till they’re needed. So, yeah, when you start to get like start to get some of that capability together, you can build some things in some really interesting ways that wouldn’t always be like, options you would choose, you know, but you’re like, "oh, wow, okay, that means I could do this thing, you know?" So, yeah, workflows can be minutes, seconds, weeks, months, years long. The Temporal doesn’t care.
Sponsor Message - XPF from Avalonia UI
Do you have a WPF application and want to take it to macOS or Linux? Avalonia XPF, a binary-compatible cross-platform fork of WPF, enables WPF apps to run on new platforms with minimal effort and maximum compatibility.
With a few tweaks to your project file, your WPF app and all its dependencies are ready for testing on new platforms.
Start your app transformation journey with a 30-day free trial.
Head over to http://avaloniaui.net/themoderndotnetshow to get started today.
Sponsor Message - NServiceBus
HTTP timeouts. Database deadlocks. In software, it’s not a matter of if things fail, it’s a matter of when. One mishap like this and some valuable data is lost forever. And these failures occur - all - the - time. But it doesn’t have to be this way.
Introducing NServiceBus, the ultimate tool to build robust and reliable systems that can handle failures gracefully, maintain high availability, and scale to meet growing demand. For more than 15 years, NServiceBus has been trusted to run mission-critical systems that must not go down or lose any data, EVER.
And now, you can try it for yourself. NServiceBus integrates seamlessly with your .NET applications and can be hosted on-premises or in the cloud. Say goodbye to lost data and system failures, and say hello to a better, more reliable way of building distributed systems. Try NServiceBus today by heading over to https://go.particular.net/themoderndotnetshow and start building better systems with asynchronous messaging using NServiceBus.
Jamie
So like a question that I just sort of had whilst you were talking about the. The long lived nature, I suppose, of workflows is that like. And it’s going to be hyperbolic and it is going to be a bit of a leading question, I suppose. But like, why do I need this if I’ve got Hangfire?
John
So, so, I mean, obviously, apart from the semantics of having to write a really good Hangfire job that’s executing, the fact that you’ve got something that’s kind of like constantly polling, constantly making an assessment for work to do, that’s sort of taking resources. Right. It’s kind of like, even if that job’s like super efficient, you know, it’s having to make, you know, "do I need to do any work," kind of thing, decisions where Temporal’s kind of like inside out. It’s kind of like it only is executing things it knows has work to do so you don’t have to have a, you know, consuming any resources that might be, I don’t know, trawling a database table or looking at queue or something else looking for work.
Basically the way it works, I think, is it keeps like the metadata kind of contained within its system. So it kind of knows when it needs to work up, wake up workflows or activities, and then kind of like, does some work against them. I think they’ve just introduced an equivalent, I suppose, of Hangfire, which is, you know, what they use, I think they call Cron jobs, which is being able to do instead of like event-driven triggers for execution, they’re basically time based. So you can say, like, "oh, every 60 minutes, go do this, kick off this workflow or kick off this activity."
But they’re predominantly looking at doing things through eventing. So it’s kind of like, "has this customer event occurred? Yes. Okay. Right now I need to go and do this other thing in an activity." So there’s a subtle difference there, but it’s really important when you get to big scale.
Jamie
John
Jamie
John
So like, you know, if you’ve trying to think of a good .NET one now, but there’s a couple of good .NET implementations around the saga pattern, which is doing kind of orchestration and understanding where it is in that orchestrative pattern and managing all of that Temporal is very similar to that, albeit it’s out of process, not in process. So if you are doing some sort of saga, again, you can do saga pattern with all things. We’ve done that a lot.
So there is definitely some, there’s definitely some overlap. I mean there’s, one of the other couple of things I haven’t mentioned up to now is actually the post-go-live. Right. So you’ve probably built systems like this as well where if you’re in a distributed system, something’s gone wrong. You know, you’ve had a customer complaint where they, I don’t know, they received the, "it’s been delivered email," but it’s, nothing’s been delivered or something. And you’re like, "right, okay, well what’s happened then?" Because you’ve had all of these sort of isolated activities or steps that have sort of had to happen. But unless you’ve been really cute with kind of like observations and using spans and stuff like that, you’re into like a really deep investigation inside logs, trying to piece together the timeline of. "Okay, well this, I can see this activity happened at like 11:12 and 300 milliseconds and this one’s happened at." And you end up, you’ve probably sat there before like me, you know, kind of like scribbling that stuff down, trying to figure out, you know, which order these things happened. "Oh no, that one threw an exception, but.
Oh well, what time was that, you know, and was that UTC? Was that you like local time?"
You know, see, quite difficult sometimes to debug that distributed stuff, whereas Temporal actually gives you this really nice Ui, basically. I mean you can look at it in the UI, but you can actually also pull it, pull it as logs and it will basically run you through, you know, the retries, all of the sequencing, all of the success, all the returns you can actually get. It actually shows you snapshots of the, of the inputs and the outputs to activities. So in the context of an API that would be, well, here were all the inputs that went into that API, this was the return codes that we got from the API. And you can do this really nice sort of investigation.
But not only that, you can see if that shows you a problem, like a transient problem saying production, but you’re like, "okay, well, we can’t reproduce this and test." You can actually ask Temporal to give you a copy of that activity journal, I suppose, for want of a better word. And then you can go and take it to your local dev environment or some other environment and replay it and ask Temporal to replay it while you’ve got the debugger attached to, basically, which is like super cool. So you can take a real world sort of production, you know, weird edge case0y kind of workflow type issue and then go replay it as many times as you like in your dev environment without having to piece together all that test data and try and recreate all of those results. And when I saw that, I was like, it just brings back so many memories of working very late at night, trying to figure out why some of these sort of really subtle things were happening. And you’re like, "oh, I can just go back to my workstation, like play it over, over and over and over again with the debugger attached and figure out what’s gone wrong," which is pretty awesome. I’ve not seen that anywhere else. And that really turned us onto Temporal, right?
Jamie
So it’s like, "go to, you know, do something in stores to actually put that inventory to one side, then go process the payment. When the payment processing comes back, which will be," each of these will be asynchronous, but we’re doing them almost synchronously one after the other, and then it’ll be like, "right, okay, send a message to the picking team. So they’ll go out and pick the inventory off the shelf and then go get the data from the client database or the customer database, sorry, that gets the information on where to send it to and things like that." And then there’s this whole process involved in actually going from user has clicked buy now all the way through to putting it on the lorry and it deliver, being delivered at their house.
Whereas, you know, like you’re saying splitting those up into services where you can, in my past it’s been putting a job on a queue and everybody looks at the queue and pulls the correct job to run and then puts maybe a different job on the queue. But it sounds like in the past when I’ve done that, like you were saying, like debugging that entire journey is, is horrendous if you split up into small services, because then you’re like, "well, where, where did it get to? Like, was it running these services in parallel? Was it running them in serial or one after the other? And where did it break? And how do we, how do we get to that point, fix that and then send it back through? Right, do we have to start back at the beginning or can we just send it back to that? Yeah, that one step that fell and carry on from there?"
John
Jamie
John
So I guess in the e-commerce world, like you said, you’d be off to do the picking, you’d be off to do the… send the email for confirmation, then you would like kick off the billing and, you know, sort of do all of that stuff. Whilst the customer has not gone on with their day basically; they assume that everything’s all fine and dandy. And then you need, you know, quite sophisticated systems to make sure that that’s the truth. So even if there is a failure or there is a transient or not or, "oh, by the way, you’ve sold something that, you know, because of our eventually consistent logistics system, we don’t actually have at the moment. So this won’t be here now until Thursday instead of, you know, ship next day. Who do we tell?" So all of that kind of intricate flow when you, when you disconnect things needs to be managed by code, right? And things like Temporal, Orleans, there’s lots of other different systems that can do that.
But like Temporal makes that much easier because you can just focus on the code, the implementation for each of those activities and then sort of put them in a workflow. And then the workflow chain itself is sort of almost self documenting. And then you can kind of like, you know, once you’ve tested those workflows, you just know that somehow this job is going to get to completion. As long as you’ve got activities for each one of those sort of situations, it’s just going to work. You know, the customer, you know, might receive an email that says, "hey look, this is going to be a couple of days longer." Or by the way, you know, we need you to give us different credit card details because we’ve tried those and they don’t work or something anymore. You know, we did like pre validation and for some reason post validation they don’t, they don’t work anymore or something. But I think they’d rather, they’d rather receive that than waiting, waiting, waiting, you know, for the, for the transaction to happen in real time. And then if it doesn’t, you know, or times out or crashes or whatever, then yeah, it’s a bad experience, but it puts all the complexity back in mine in your lap, right, as software developers?
Jamie
John
What we do is stuff that’s non-trivial is we actually produce swim lane diagrams. You know, the ones with like, sort of where you have like columns and then you’ve got like flowchart objects typically, and we’ll have a swim lane per external service or external component or whatever, and then we sit there and we draw it out. So we, you know, have activities as a certain shape and we have like workflow as a different shape. And then, and then we sort of do all of that planning upfront so that we have a good idea of the structure of the workflows and the structure of the activities and who’s got to do what. You don’t necessarily need to know exactly what the code implementation is going to be. That helps a lot, I think, with figuring out the elegance of the workflows and you don’t suddenly have somebody say, "oh, yeah, but what about this scenario? What about this scenario?" It still happens occasionally, but you’ve done a lot more planning up front.
Jamie
And like you say, you’re able to then concentrate on the important bits that we have to like, okay, so I’m going to go on a bit of a rant and it’s got nothing to do with Temporal, right. But I feel like I need to get those off my, off my chest. Right: The DevOps movement is fantastic and it’s great, but the problem that I feel it has caused is it’s become "developers focusing on infrastructure and how all that works and how it’s all glued together and how the process works." Whereas actually, realistically, when you dial it, when you boil everything out, dial everything down, metaphor your metaphor, the way out of it, you actually find that we should be writing the code which produces the results that the business wants.
Yes, we should probably have our finger on the pulse of how it’s going to get developed and deployed and how it’s going to live in the world. But realistically, we are hired to do a whole bunch of stuff, but one of the things we’re hired to do is to turn that human language business logic into computer language business logic. And I like the idea that Temporal, from the sounds of it, allows me to not worry about how these things are connected together and how we communicate across them. I can just say, "hey, I have service. It could be micro, it could be monolith, it could be whatever, a over here, service b over there and service c over there. When app talks to service a, somehow we need to get a message to both b and c, and both of those need to send a message back to app somehow. I don’t care how. I will tell you what a, b and c need to do, because I will give you the code for them and I will tell you what app needs to do because I’ll give you the code for them, but I need you to figure out how to glue it all together."
It sounds like that’s the case. Is that the case?
John
But coming back to your DevOps point, which is one of those things that I think was, got widely misunderstood really. And we at Applicita, we have, all we ask of our developers really is to have an appreciation of the infrastructure and sort of particularly take responsibility for what’s coming out from an observability point of view out of the software they’ve written. We don’t really, we still, it’s not a silo because people think, oh, Silos is a negative thing, but it’s more a case of, "these people over here have a really deep knowledge of, you know, rolling out Azure this and Azure that. These guys over here have a really deep knowledge of like .NET. They have an appreciation of what each one of those people do and they’ll sit in a huddle if they need to and kind of like figure stuff out".
But like you say, this movement to a few years ago is kind of like implying that, you know .NET developers suddenly had to be, you know, experts in like all, how many would you think? 500 services in Azure, maybe 350 or something. As well as being good.NET developers as well as being good business analysts and stuff, I think you’ve hit the nail on the head really where as developers responsible really for the validity and the quality of the code that we produce. I’d much rather developers were sort of focused on the correctness of what they were doing than worrying about, you know, some bit of tin somewhere sitting in, you know, sort of some data center in Azure. You know, I just don’t think that’s, I’m sure it wasn’t intended that way, but that’s how it got interpreted by a few people. Right. Do you agree?
Jamie
John
Jamie
John
Jamie
John
Jamie
John
So like you say, it’s a mindset. I mean, it does drive you bonkers, though, because try advertising for a job role. Now, for somebody that’s in infrastructure that you can’t, where you don’t use the word DevOps, like, nobody applies for it because they don’t know what it is. So you have to use the word in order to get people to. Oh, right, okay. It means this, you know, so, okay. If you like, you know.
But, yeah, yo it does irk me a little bit. I have to throw the word around. But, like, say it’s a culture, not a. Not a skill, you know?
Jamie
So then I guess sticking with that DevOps idea, right. Somebody may be listening to this and going, "but Kubernetes lets me do durable things, right. In that like I could put all my po, all my code in pods and if a pod dies, it will start a backup." But that’s different to Temporal, right? Because my, so my understanding is if, if I have a service that is being hosted by Temporal and that service goes down, the work that it was doing can still be sort of rescued, is that right? Whereas like with kubernetes, if I have some code in a pod and it’s processing something and then the pod goes down and is replaced by a different pod, then that processing is gone, right? All that data is gone.
John
Jamie
John
So the way that the .NET implementation of the Temporal works is really nice, right? So if you’ve ever used ASP .NET like service host or whatever the non ASP .NET version of that is, you know, you normally get a nice knot of extensions that say, you know,
addTracer or addSwagger or whatever, you literally can say like addWorker, addTemporalWorker and then you tell it where the server is and then you can start registering workflows. So you can say like .AddWorkflows(…) you don’t have to do them.So compile time, you can do them at runtime too. So literally to get Temporal up and running in .NET is like super, super simple. And what’s happening behind the scenes, I believe is that it’s firing up. Do you remember the background service functionality they brought into .NET Core? It’s firing that up and it’s basically bringing up the worker role. So it’s registering with the server to say, "hey, I’m ready to do work," and all that kind of stuff. So if you then zoom out a little bit and think about, okay, so my .NET code running in my pod, in a Temporal world, you’ve got your.NET code which is running also this background service which has got the worker role in it and then that’s executing the activities that are handed to it by the server.
So let’s say your Kubernetes server decides this pod needs to be evicted for some reason or like say crashes or whatever. What happens is that obviously that pod dies, new pod comes back online, brings up the, brings up the .NET code, just, you know, just your regular, you know, exe or whatever that starts up the worker again, the worker then like re-registers with this thing and says, "hey, I’m ready to do work. And the server will say, well, "okay, I’ve lost this other one. And it was in the middle of doing this and, you know, we saved this state, you know, halfway through this activity or whatever," and then it will just give that, you know, with the right, if that’s the most important thing to do next, because there’s a whole bunch of policy stuff and priorities I won’t go into right now. But let’s assume that for now there’s nothing else to do. It will just basically pass it that job and say, "here’s where you got to, here’s the state that you were in, off you go." And it will just, you know, pick up where it left off kind of thing. So it’s actually doing two things. It’s not, it’s not just running, it’s not marshalling, you know, the running of code. It’s also saving state.
I mean, I’ve seen people build a fairly rudimentary sort of whole actor system just in Temporal, because, you know, you could literally actually, the way that it follows the same rules actually, as JSON, the new System.Text.Json Namespace. So if you could serialize the object, you don’t even have to, you could just have like objects in your executable code and never have to save them and never have to persist them anywhere because Temporal does it for you. So you could just basically like live off of local variables if you wanted to, to. And it sort of basically will dehydrate anything that’s running in that, or the values of any of those things in the activity, and then rehydrate them again when it’s needed, if it’s died, or because that activity needs to run again or whatever. And yeah, it handles all of that. So you sort of get the state persistence as well as sort of Temporal’s workflow marshalling, I guess you’d call it, which is pretty neat.
Jamie
John
Jamie
John
I mean, there’s a couple of different ways where you can set your own development environment for the Temporal server itself. My favourite is to use cocker-compose. So I use, you know, Docker desktop and then use cocker-compose to bring up the Temporal server. But you don’t have to do it that way. You could either have a local install in your dev environment somewhere if you’re sharing with other developers, or I believe you can actually run it even from the command line. So they give you a cut down version of a bit like the .NET CLI kind of command line. They have an equivalent Temporal one. And you can do, you know, Temporal server start or something. It’s just my preference is to do, is to do it through, is to do it through Docker.
And then you can immediately, so your code is up, you can immediately go into the UI and it will show you the health of the worker and stuff. So you all know straight away that the work is up. So you don’t even really need to register any workflow or activities. You could just get yourself going with like two or three lines of code, point it at your local docker environment or your local install, and then you’re, and then you’re up and running.
Jamie
John
In fact, the talk I did with Temporal, I sort of mis-drew a diagram which I didn’t realize that the diagram was wrong actually, until I actually did this sort of presentation. So I sort of implied that there was like a worker per instance. So, like, let’s say you had like an e-commerce system and it was behind a load balancer and you’ve got, I don’t know, three instances of that or three pods, say, running in. You don’t, you don’t need to have three workers you could, like, if you wanted the same code, to just be running on every one of those pods. But an equally valid way would be to leave the e-commerce system exactly as it was and then build another little tiny piece of .NET that did nothing else other than start the worker process and then deploy that to a pod so that you had these kind of like three e-commerce systems, all referring to, with their Temporal clients, all referring to a single Temporal worker.
They’re incredibly efficient and they, they obviously, depending on the length of your activities and the length of your… they can process, you know, phenomenal amounts of instructions and stuff. So, yeah, you don’t have to, you don’t have to do as my, you know, don’t you hate that when you realize, like, you…I’d spent this pages on this presentation. It was only actually, while I was presenting, I was like, this diagram is wrong. But, yeah, you don’t, you don’t need to have an instance, instance per thing if you don’t want to. I would. I would probably steer away from that, actually. I’d probably put it in a separate place to start with and then get comfortable with load and, you know, understanding, you know, how many of these workers do you need to, like for your workload and then go from there.
Jamie
John
The thing about understanding Temporal as well is it gives, it opens up options that you, as an architect, you might, it changes your cost value calculation a little bit. You know, as an architect, I guess, or as a really senior developer is, you might want to put some of this kind of extra resilience into the system, but the cost of doing it is too high. So you end up with like, known fragility in your system and it’s, you know, a reasonable payoff because you know, that you can’t afford the cost of, you know, securing that particular transaction or whatever.
If you bring Temporal to the story, then those dynamics change completely. So you can afford to make everything super robust, super, like, they call it indestructible kind of, because there’s no, the cost to do so is so low, you might as well do it all, which just generally means that you end up with a, you know, super robust system. Because no matter what smart decisions you made as an architect on a sort of ROI basis, that one thing you left as a, you know, as a thing that’s like, "hey, like, it’s very unlikely that’s going to happen. You know, we can’t afford the time or the money to sort of shore that one up." You know, that, that will bite you on Friday afternoon at some point, about 04:00, you know. So yeah, it does change the fundamental value decision making that you, that you need to make when you, when you, when you’re building some of this stuff.
It’s pretty easy to retrofit as well. Like if you’ve got, you know, we’ve looked at some code bases that aren’t Temporal. We write pretty clean code. So, like, you know, we do a lot of, for instance, like mediator. So if you’re, you know, if, you know, if you have commands and command handlers and, you know, you’ve got some reasonable level of separation of concerns in your code, it’s really easy to Temporalize it if that’s a word. You know, you can kind of create a, create a new class if you want, or put in a new method, and it’s literally like an attribute. So if you’ve got reasonable amounts of separation, you could just like, "okay, well, what we’re going to do is we’re going to leave the current code as is. We’ll take a copy of it, we’ll put it in this new class with this new method, and then we’ll put the correct sort of attributes on it to decorate it, and then we’ll have some feature switches or something that could like switch between, like how we used to do it and how we’re doing it now with Temporal."
And, and, you know, if you’ve got a big ball of mud, that’s obviously going to be a little bit more difficult. But that’s true of any refactoring. Right. But yeah, we’ve definitely looked at some stuff we’ve built for clients and said, "hey, the next time you want us to do some versioning, we’ve got this idea where we can, you know, we can do like a big improvement," but we can move, you know, this code from here to, and what we did, which was, you know, sort of our poor man’s version of Temporal to Temporal, you know, in a really easy way, and then they just get a much more robust system almost for free.
Jamie
So like if I’m gonna, you mentioned a few times they, they have their own hosting platform that I could host my apps in, if I use Temporal, like do I have to use that or can I go, hey, I want to host it on Azure or AWS or things like that. Like am I tied into their service?
John
So yeah, the only, the cloud bit that they have provides is just the Temporal server. So you don’t have to move your workloads or move your apps or anything like that. It’s literally the back plane, if you like, of Temporal. They have like a SaaS service which is automatically scaled and super secure and all of those good things that you’d expect from a SaaS platform. But you absolutely don’t have to do that. You can run the whole Temporal server yourself from docker containers, for instance. So you could put it wherever you like, AKS, EKS, VMs, whatever. You can even not run it in containers, I believe. I think you can literally download the, there’s a lot to it. So certainly the guidance we’ve been given, "unless you’re really proficient at progress and elasticsearch and you know, one or two other tools, don’t run it in production unless you really know what you’re doing," because it is the, I guess the single point of failure. So if your Temporal server was to go offline or be broken or not be performant, then you’re going to break the, the performance of the whole thing because the workers won’t get there, you know, won’t get told what to do, they won’t be able to reliably send their updates, all that kind of stuff. So I’d probably advise, unless you had, if you looked at the stack and said, "we’ve got deep skills in all of these things, don’t worry." Then great. But if you didn’t, I would, I would, I would go with the Temporal cloud thing because it’s, it’s super cheap.
Jamie
John
I mean, the workers themselves will carry on doing the work that they’re doing, but of course they can’t phone home so they can’t say, "hey, this activity is finished and stuff." So if you were then to get a sort of cascading failure, I don’t know, it’s pretty, going to be pretty rare, but if you had like a Temporal server that was offline or broken, and then you had a worker that was offline, then went offline after doing some new activity, then you’re going to lose, you’re going to lose where it was because it will bring itself back online and it will obviously have all of its state that it had and, you know, will try and recover itself. But it didn’t, it didn’t get that information back to the server, so it can’t say to the server, "hey, what’s next for me?" Kind of thing, you know.
So you don’t get like day loss or anything like that. But, but it gets kind of stuck because of the orchestration of that workflow and stuff is being done by that centralized environment, which is why Temporal themselves like people to use the Temporal cloud system because it’s like Uber resilient and I think, I believe it’s all hosted in AWS and they’ve got, you know, a global environment where Europe and the US and you know, lots of other places where they’ve got the Temporal backplane available so it doesn’t, doesn’t suffer with any even data center related failures, you know, it’s pretty, pretty neat, right?
Jamie
John
Jamie
John
This is where, because the .NET SDK is like new. And by new I mean, I think the official GA, I mean, we started working on it about 18/12 months ago, I think 18 months ago maybe, but it only GA like a month ago, I think six weeks ago maybe. The documentation, they’re still catching up and there are a lot of I wouldn’t call them "hello world" examples. But if you go to the GitHub samples, there’s a sample for every feature of Temporal, you know, written in .NET. There’s a really great guy over there who did the .NET SDK, and he’s put a lot of effort into showing how to use each one of the activities.
But the thing that’s missing at the moment and the thing that we like working with them is, "how do you put all these things together in a best practice way to sort of show, you know, to show how to use it all in context." And that’s definitely missing. So where we’re using it, we can’t share that code because it’s like a client project. So we’re talking to Temporal about maybe taking like eShop or, you know, some of the sort of more famous known, sort of exemplars, I suppose you call them, and then kind of, you know, take a fork of one of those and then Temporalize it and then give it back to the community for free and say, "this is how an end to end application would look like using [Temporal]." I mean, they do have end to end examples, just to be clear, in lots of the other Languages. So if you did know Go or TypeScript or they’re the two I focused on, then you could go and look at those and then do the translation in your head and say, right, "oh, okay, I know what the equivalent of the .NET version of this would be."
But we, we really want to work with them to, you know, get a bonefide eShop like thing that, you know, everybody knows and loves and go, "oh, right, okay, I see what you’ve done here." You know, it’s like, you know, looks like this in .NET and, and that, that’s kind of what’s missing at the moment. So, yeah, it’s, it’s, it’s early for sure.
Jamie
John
Jamie
John
But places to go where I, where I found useful, definitely Temporal's YouTube channel, both their own channel. And if you just like to type in like "Temporal IO" as well, you’ll find other people that have done some talks. But Temporal have been really good right from the outset. So if you’re looking for primers on Temporal, you know, done a better job of explaining the principles of Temporal than I have today, definitely go to YouTube. You can see some, some great 101 stuff from them and 102 stuff from them about that.
There’s actually a video on from Chad, who’s the guy who did the .NET SDK, where he talks towards the back of the video about using the SDK. But quite a lot of the video is about how he came to create it, how he came to create the .NET SDK and what that, and what that took because it was non trivial, as you can imagine.
Yeah, samples in GitHub.
The trick I use, and there’s a few around now, is if you go find the activity attribute, which I think is as simple as like
[activity] or look for the namespace, I actually search through GitHub looking for the Temporal namespace declaration. And you can, you know, it pulls up what people are doing and certainly over .NET, there’s a lot more people doing some non trivial stuff now. There’s some people experimenting, you can see with like logistics flows and stuff. I see, which is, you know, one of the key, you know, one of the key places where I sort of see it really shining, you know, where people are, got long supply chains and they’re, they’re figuring that stuff out.The readme is really good because Chad knew that it was going to take a while to get the documentation parallel with, with what’s already there. So like the actual readme in the, in the, in the .NET SDK is awesome. He spent ages on it.
And yeah, I mean if you, if you got stuck with a specific, you know, with a specific thing or you just, you know, needed some more input, then obviously you could reach out to me too, and I could put you on touch with, you know, one of our team members or look at it myself, whatever.
So yeah, it’s like I say early, but there’s, you know, quite, quite a bit around and you, they’ve got a really good slack sort of ecosystem as well. So like the whole company, Temporal company is on Slack and they invite like the public basically into the same Slack channel. So there’s one there for the .NET SDK. And I’ve really seen over the last two or three weeks the traffic increasing in that, lots of questions, lots of people trying things out. And there’s a couple of us, you know, people that don’t work for Temporal that are in there kind of answering questions. And then Chad, Chad’s in there all the time as well. So yeah, there’s a plenty of, what’s the word? I’m looking for non formal kind of support out there now, and it’s very quickly going to become formal as they like, you know, bring it on par with, with TypeScript and Go. And some of the other languages.
Jamie
So then just as we wrap up, then what about getting into contact with you? Right. If someone’s listening to this and gone, "I need, I’ve got this burning question to ask John and maybe you can, like you said, maybe you can put me in the right direction of the person to talk to or whatever." How does someone go about getting in contact with you? Is it Twitter/X? Is it LinkedIn?
John
Jamie
Well, like I said earlier, I’m going to make all of the, all of the links and things available in the show notes. So if you do want to click through and find out more about Temporal or get in touch with John, then that will all be there. And I guess that really all that’s left to say is, thank you very much, John, for being on the show. I know that I’ve learned a whole bunch of stuff. I always say this, right, but I genuinely, genuinely mean it.
I came into this, into this episode with like, "I know that Temporal IO is the URL and I know that Temporal is a thing. Teach me." Right. But I genuinely, I’ve walked away from this with like. Right, okay, I gotta go build something that I can maybe put in Temporal and get my head around a durable workflow design because I’m pretty sure that there’s a project I’m working on that should be using a workflow like design.
John
Well, thanks a lot for having me, Jamie. It’s been great to talk about Temporal. Yeah, I think probably if we all looked at various different things we’ve built, especially if you knew Temporal, you just could put it into pretty much any, even small apps and you get a big benefit from it. It isn’t just like a full, big, full blown enterprise thing. There’s a little bit of a learning curve to it. But once you get your head around the learning curve, just like with anything, then you’d be like, "oh yeah, okay, we need to send an email out and make sure that it does really go out. Okay, let’s do this. You know." Yeah, it’s pretty cool.
And you’re gonna see the Temporal guys bringing out some even more interesting stuff over the next sort of six to nine months which and now they treat the sort of .NET SDK now. It’s like what, you know, what they call first class citizens. So it’s kind of always going to be parallel with all of the other stuff. So although it came late, it won’t lag behind. It will now be kind of on par with everything else.
Jamie
John
Wrapping Up
Thank you for listening to this episode of The Modern .NET Show with me, Jamie Taylor. I’d like to thank this episode’s guest, John Kattenhorn, for graciously sharing his time, expertise, and knowledge.
Be sure to check out the show notes for a bunch of links to some of the stuff that we covered, and full transcription of the interview. The show notes, as always, can be found at the podcast's website, and there will be a link directly to them in your podcatcher.
And don’t forget to spread the word, leave a rating or review on your podcatcher of choice - head over to dotnetcore.show/review for ways to do that - reach out via our contact page, or join our discord server at dotnetcore.show/discord - all of which are linked in the show notes.
But above all, I hope you have a fantastic rest of your day, and I hope that I’ll see you again, next time for more .NET goodness.
I will see you again real soon. See you later folks.
Useful Links
- temporal.io
- Polly
- Durable Tasks from Microsoft
- Azure Event Hubs
- Azure Service Bus
- Cadence
- Godot
- Hangfire
- Saga pattern
- System.Text.Json Namespace
- GitHub samples
- eShop
- Temporal's YouTube channel
- Temporal's Slack
- John Kattenhorn on X
- Supporting the show:
- Getting in touch:
- Music created by Mono Memory Music, licensed to RJJ Software for use in The Modern .NET Show