Skip to main content

Boiling the Frog

About this video

Organizations are resistant to change, but it may not be for the reasons you think. When it comes to modernizing an application, navigating corporate bureaucracy is often the largest hurdle. Coordinating across multiple departments can be cumbersome and time-consuming. Dev teams often get stuck in a cycle of “hurry up and wait”.

Most talks about modernization talk about the strangler fig pattern. In this session, we will go beyond strangler fig to discuss how you can leverage technical solutions to subtly but effectively overcome bureaucratic challenges.

By empowering your team to move the ball forward, get things done, and achieve as much progress as possible independently, you will have happier developers and happier stakeholders.

đź”—Transcript

00:02 Jay Erdahl
Here we go. We are broadcasting.
00:15 William Austin
Okay. Tonight's speaker is Hazel Bohon. Hazel is a software engineer and mom. With over a decade of experience working across range of industries, she has a passion for solving problems and building reliable, scalable, maintainable systems. When she's not debugging code, you can find her down at the lake fishing with her kids. Hazel, take it away.
00:40 Hazel Bohon
Hello. Today I want to talk to you about software modernization. In this presentation, Boiling the Frog, Implementing a Modern Message Based Architecture Without Anyone Noticing. We're going to walk through a basic process for this.
00:59 Hazel Bohon
So, who am I to be talking to you on this subject? My name is Hazel Bohon. I'm a software engineer. I've worked across several different industries and have been involved in application modernization and migration efforts within organizations of varying sizes throughout my career. Today, I work at Particular Software, where we make NServiceBus, a message service bus that helps organizations produce distributed, message-based systems with a minimum of boilerplate code. When I'm not working, as William said, I'm spending as much time outside as possible outside with my kids, kayaking, foraging for mushrooms, exploring parks, and just generally enjoying the beautiful Minnesota summers.
01:39 Hazel Bohon
Modern application design patterns, which are generally understood by the industry to represent best practices for producing applications that are reliable, reusable, extensible, and maintainable. Legacy code applications on the other hand, typically exhibit idiosyncratic behavior and often use out of date, no longer supported software packages. To steal from Tolstoy's Anna Karenina, "All modern applications are alike, but all legacy applications are dysfunctional in their own unique ways." The challenge of modernizing a legacy application can feel daunting, it can feel overwhelming, but it is possible to navigate these challenges without burning out your team. Today, I want to talk through the basic process for approaching this. Please consider this as a framework, a series of guideposts for navigating through unknown territory. This is not a map, it's more of a compass. It's not an algorithm, it's a set of loose heuristics.
02:45 Hazel Bohon
The strategy which we have found to be most effective for modernizing an application has been to start by understanding the outcomes you want to achieve, deciding how to break the problem into smaller parts, successfully delivering those parts, and changing the organization to allow this to happen on an ongoing basis. In this presentation, we will discuss how to achieve each of these pillars.
03:10 Hazel Bohon
Fundamentally, change is hard. If a legacy application exists in production, by its nature, it must be fulfilling some sort of business need within your organization. And it's doing so well enough, your business relies on it, while it may be a source of tremendous pain for your team. It is not necessarily the case that everyone in the organization feels the same way. I have worked on projects where many stakeholders would complain about the performance of the existing legacy application, but when we tried to introduce a replacement, we often ran into resistance.
03:46 Hazel Bohon
Everyone at my first job, everyone liked to complain about this green screen console-based application that we had, but when we attempted to replace it with a more modern graphic-based user interface, everyone found it to be nearly unusable. They had years of experience using the old terminal-based interface. They knew all the hotkeys, all the tricks, all the shortcuts, all the workarounds to make it work quickly so they could continue having conversations with their customers while also looking up information. Although they may have very much enjoyed complaining about the outdated user interface, they still knew how to use it effectively to get their job done.
04:26 Hazel Bohon
And it may be the case that you're dealing with a similar situation where you get pushback from people within your organization when you attempt to replace existing applications. A common phrase is, "They moved my cheese," and so, although you may be spending large amounts of time on the maintenance of software, you may be spending an inordinate amount of time to deliver new features, it can be the case that there's still people in your organization who very much rely on that existing system. And so, getting buy-in from these stakeholders within your organization and customers outside your organization, depending on the specific application, is often the biggest challenge in getting an application modernization project. Figuring out an approach which will minimize disruption to the rest of the organization is often paramount to achieving the goal of modernizing an application.
05:31 Hazel Bohon
If you're here, you're obviously interested in application modernization, and so it's easy to assume that we know the reasons why we want to do it. Of course, we want to do it, right? No one wants to be maintaining that old vb.net app or that VB6 application. No one wants to be on COBOL. We all know that modern engineering practices are better, we just feel it, it's taken as a given. But it can be worth taking a step back and thinking for a moment about the actual concrete benefits that are offered here, and modern code is easier to maintain and it's easier to onboard new people.
06:08 Hazel Bohon
I remember at a previous job I worked at, we were using a language called AlphaBASIC for our legacy system. It's a subset of BASIC that as far as I can understand is in production nowhere else in the world right now, other than this small regional electric supply reseller in Texas. When you first joined as a new developer, they would hand you a Xerox copy of a Xerox copy of a Xerox copy of the original manual for the code base. There was nowhere to find any information on it on Google search, there were no Stack Overflow answers. None of the tools that modern developers normally expect when coming up to speed on a new language were present or available. This was, to say the least, a less than ideal experience for junior developers coming onboard. Many of them at this organization, this was their first job, and so it was a tremendous challenge onboarding new people and getting them to be able to work confidently on the legacy system.
07:11 Hazel Bohon
In addition, you have code which is more reliable, more secure, more robust, and again, more reliable when you move to more modern patterns for building your applications. And then fundamentally, all of this leads to making it easier to change and deliver value to the business as a whole, and that I think is the core benefit, the real reason that all of these other things are important, why they matter, and it's the thing that's enabled by all of them. This is the thing that you need to sell stakeholders on within your organization, that it will be easier for you to make the changes that they require. It'll be easier for you to deliver value to the rest of the business.
07:53 Hazel Bohon
So, it's so obviously beneficial. Why is it that organizations resist this? Well, people are kind of skeptical of the unknown, and I know that I have heard many people say, "I've been burned before on the new software," right? There were all of these promises of something amazing that was going to come down the pike, and then it got mired in years of development. And then when it came out it wasn't really complete and you always have some missing feature that was super important to you before, or it can be difficult to justify these large-scale rewrites of legacy applications when that can take years to do. But at the same time, organizations often think in terms of quarterly returns on investment. How can you justify annual investments when you see no concrete benefits in reasonable time windows? And if it ain't broke, don't fix it. So, these are all objections that we have to overcome when trying to modernize software.
08:56 Hazel Bohon
It's very tempting to go... There's a Seth Goding quote that I'm very fond of that I think describes a lot of the problems that we run into when we think about software modernization efforts. "Big problems get big because systems amplify problems and make them sticky. It's tempting to decide that a chronic problem is big enough that we ought to declare war on it, drop everything, hyper invest, hold our breath, and do nothing until it is solved. But that's not how the problem got here, and it might not be the best way for the problem to be solved."
09:31 Hazel Bohon
If you're dealing with a legacy application that's been in production for decades, as is often the case, you're looking at a code base that's highly, highly developed, highly robust, and includes a lot of edge cases. It's pure hubris to think that you can just come in and replace this in very short order. There's a lot of embedded business logic in there. There's things that it's doing that are probably not documented anywhere else. Things that were added by someone who doesn't work at the organization anymore. For reasons that are not fully understood by anyone but will ruin quite a few people in your organization's day if you suddenly remove those capabilities.
10:15 Hazel Bohon
And I also find this meme to be a very good description. When we are modernizing our software systems, we have to move at a more gradual pace. It's slow and incremental, the process by which we do this. I've been trying to exercise more because I know it's going to have good, positive outcomes for me, but on a daily basis, it's not so easy to motivate myself to do so. And I think it can be a similar thing within organizations.
10:43 Hazel Bohon
So, the fundamental challenge we're facing here is migrating this big ball of mud, legacy code base. We need to take it as an incremental approach. That way, we can move move things over while not disrupting the existing deployed infrastructure. We can't do it all at once, and by making the process more gradual and incremental, it is the case that we can begin delivering new features more quickly over time and show benefit to the organization as we move through the process of the migration.
11:24 Hazel Bohon
One of the problems is that organizing the functionality, when we're talking about moving into message systems, when we're talking about moving that functionality over, we run into an issue where actually organizing the functionality of a business into discrete services, finding the service boundaries between different business units can be a very challenging problem for us to try to have to solve. It is often described, it's well described as a wicked problem.
12:00 Hazel Bohon
The wicked problem term comes from Dilemmas in a General Theory of Planning, written by Rittel and Webber in the 1960s. In the first half of the 20th century, it had been the case that we had seen time and time again, experts being trusted to build new things. New roads, faster cars, engineering problems had yielded results time and time again, and there was a great deal of trust in experts. However, as we moved into the second half of the 20th century, the professional class began to run into issues with people pushing back against expert decision-making processes. Rittel and Webber identified that the thing that had shifted was that experts were now being asked to solve these wicked problems.
12:53 Hazel Bohon
And I know there's a ton of different characteristics that I've got listed there, I wanted to highlight the three that are in bold there. That there's not really a defined stopping rule. In other words, right where they lack an inherent logic that signals when you've actually fully solved it. Application modernization falls neatly into this. We can divide our service boundary, we can create our service boundaries, but it's entirely probable that the first time we've done it, we're going to get a little bit wrong. We're going to need to move things around and shift things, and we need to be open to the idea that our first draft of the solution is going to be incorrect and that we're going to have to make attempts at solving this before we've actually managed to successfully solve it in a way that really works and delivers value to the organization.
13:41 Hazel Bohon
All wicked problems are essentially unique. As I said before, all legacy applications are dysfunctional in their own unique ways, and this is also the case here when we're modernizing for a business. Every business has its own slightly unique needs, and we need to be able to tease all of that out of the existing legacy application and what documentation does exist for it as we're building our service boundaries.
14:05 Hazel Bohon
And the way a wicked problem is described determines its possible solutions. I don't know if you've ever been talking to someone doing requirements gathering, but you can run into an issue where the way they described the problem in the first place very much predispositions everyone towards the solution. And taking that step back and asking, okay, but what are you trying to achieve here? What is the goal? And trying to dig down to understand the problem is something that you can easily miss when you're doing requirements gathering. And so I think in all three, all of these attributes very much apply to when we are attempting to do software modernization and we're attempting to define service boundaries.
14:53 Hazel Bohon
One good place that we can start when building out the service boundaries, a simple heuristic, is to follow Conway's Law. "Organizations, which design systems in the broad sense used here, are constrained to produce designs, which are copies of the communication structures of these organizations." We can assume that service boundaries built around the existing org chart will get at least an approximation of the appropriate structure for dividing up our services.
15:27 Hazel Bohon
Okay, so having discussed this at a higher level and some of the general rules of the road for it and why we're doing this, let's go ahead and cook this frog. So the first step is the first step, the step zero for software engineers. We always have to start our list with zero, right? Starts with code hygiene and best engineering practices. So this can be trainings, such as brown bag lunches where everyone shows up and instead of going out to lunch, everyone packs a bag and meets in the conference room and has a discussion about or has a tutorial to go through some new technology that's of interest. It's a great chance for people to work on presentation skills within the organization, and it's also a really good chance to make sure that people on your team are familiar with technologies that you may be using in your new platform.
16:25 Hazel Bohon
I've talked to entirely too many people who have run into this problem where they were told, "Okay, you need to move to Docker, you need to move to Kubernetes, you need to move to Cloud GCP." No one on the team is familiar with any of those things, and then there's a complete failure of anyone to be able to get up to speed quickly on it because there wasn't time taken for this basic build-up of knowledge and knowledge sharing within the team.
16:50 Hazel Bohon
In addition to that, you're going to want to build out unit tests if you don't already have them. I know we all have some unit tests in our code base, and everywhere I've worked has had unit tests. But some places I have worked have had unit tests that actually were useful, and other places I have worked have had unit tests that were well-intentioned, we should just say.
17:13 Hazel Bohon
Similarly, with code reviews. I've worked at places which have taken code reviews very seriously. It's been something that people take time and figure out and look and find reasonable feedback to. I've worked at other places where any code review would almost immediately receive a LGTM comment on it and be approved for merge.
17:38 Hazel Bohon
CI/CD pipelines are also an essential thing to begin adding at this step. One of the things that we've done here is we haven't even really started the turned on the stove. This is sort of the prep work before we're actually doing any cooking here. This is all stuff that can happen inside of our team that doesn't have to involve anyone outside of our engineering team, and basically prepares us for the next steps in this process of migration, make sure that we start with the best footing possible.
18:11 Hazel Bohon
Another thing that's reasonable to do at this point, or that's excellent to do at this point, is to look for a hype man, someone who can sell the benefits of the migration as it's happening. This can be someone who's on your team or someone else in the organization, but you want to find somebody who is going to be able to promote the work that you've been doing, someone who can share the value of the changes.
18:36 Hazel Bohon
I don't know if anyone else has experienced this, but anytime I talk to someone who's not in software engineering, if they work in an organization that has a software development team, I always want to ask them about it because that's my profession, that's my thing that I understand. And the thing that I always get is sort of a blank stare and a, "I don't know what they do, I don't know anything about it. I just know it's important, and so I just try to leave them alone." And we want to break that down a little bit inside of our organizations, because having people understanding the things that we're providing, the benefits that we're delivering to the organization as a whole is essential to getting people on board with investing in software modernization, on staffing up, on other growth-oriented approaches to the software engineering teams. And so this person, the hype man, is a good thing to have to kind of help build that and facilitate that within your organization.
19:36 Hazel Bohon
In addition to that, you want to look for one or more, you want to look for guides. People in the organization who aren't necessarily on, who aren't on your team, but who know things about the rest of the organization that you as a software engineer might not necessarily know, right? Someone in accounting or something like that.
19:55 Hazel Bohon
I recently moved to Minnesota and I had no idea how to live with snow, I came from Texas before. And I made several friends in the area who've been very, very helpful and helped me through the admittedly somewhat mild winter that we had last year. One morning I woke up and I went outside and I was about to go and start shoveling the snow that had fallen, and I got a text message from my friend and in it they said, "Be careful this morning. This is what we call heart attack snow because it's super dense and you can really easily overexert yourself." And sure enough, when I went to go shovel the snow, it definitely was heavier and I'm not sure that I would've noticed that. So, having this guide, someone who already knew about the things I didn't know I needed to know about, was immensely helpful for me in moving to Minnesota.
20:52 Hazel Bohon
Yeah, and so you want to find these personal connections outside of the org chart, people elsewhere inside the organization. Water cooler chats are a great way to start finding people like this. Affinity groups inside of the organization can be really helpful. I have a friend who she was able to find some very meaningful contacts within her organization that were able to help her come up to speed on some of the things that she wasn't familiar with, because she got onto the various work Slacks and just posted a bunch of memes here and there and was able to make some connections and get people that were interested in going to lunch with her, interested in hanging out with her, interested in talking about things that weren't work.
21:36 Hazel Bohon
And you want to establish these unofficial touch points across the organization so that you have people that you can reach out to when you're stumped about something. Some piece of business logic, some process, who it is you need to talk to about something.
21:50 Hazel Bohon
For building these connections, authenticity is an essential, is a key. It's much better to have one or two people in a department who really like you, who get along with you, who have inside jokes with you, who understand you as who you are, as opposed to having everyone being passingly familiar with you with a generally vaguely positive disposition towards you.
22:18 Hazel Bohon
So having set this up, we've now got everything, we're ready to go. We have someone who's going to be able to trumpet our successes. We have talked to people across the organization and in a very low-key way, created these connections. We've leveled up our development team so that we're ready to take on a challenge like this. Now we begin with step one, laying the groundwork. So we're going to start publishing events, we're going to emit messages in places at the end of method calls. And we don't necessarily need to have these actually going to a dedicated message queue system like RabbitMQ or anything like that. We can actually just send these into a SQL database table. The important thing is that we're just sending them somewhere, but they can be accumulated and picked up by some future use case.
23:15 Hazel Bohon
So for example, when an order is placed, let's just at the very end of that, we can add a order placed message that gets put into a queue that can be consumed later. We don't necessarily know at this point who's going to be consuming it or for what purpose, but that's not really the point. The point is to create the ability of future functionality to hang off of that as opposed to having to go into our order place logic.
23:42 Hazel Bohon
And now, we can move onto having done that across your code base for some time. What you're going to have done is you're going to have created a series of messages that are being emitted. You're not going to necessarily have taken much time away from just doing your normal day-to-day app development.
24:02 Hazel Bohon
Moving into step two, you're going to take a little bit more effort here. Now we're going to actually start creating subscribers to the events that we created, that we were publishing in step one. We're going to pick these opportunistically. When people in the organization are asking for features, if we find one that's a good example or that's a good opportunity to go ahead and add something on, then we want to jump on that.
24:26 Hazel Bohon
So, I had a previous job where I worked at where we had some folks who worked in the warehouse and they often didn't notice when a hotshot order came in for the wire cutting room. This was the electrical supply reseller again. And so, one of the things that what we were asked to do was to put a siren into the warehouse that would go off, much to the chagrin of the people who were working in the warehouse. We set it up, and then we were able to simply take that order placed message that had already been put into a queue. We were able to grab that and we were able to then consume that for sounding this alarm, provided that it followed certain conditions. So, we'd created a message subscriber as a functionality, which we had no idea at the time that we created the order placed message.
25:28 Hazel Bohon
And these sorts of functionalities, we're going to be adding them opportunistically when it's possible, when it makes sense, when it's reasonable. We're going to be trumpeting the successes whenever we're able to deliver something a little bit more easily, a little bit more quickly, and we were definitely able to deliver our alarm system for the warehouse folks more quickly by using messages. You want to make sure that your hype man is talking this up. You want to make sure that people are recognizing that this is something that you're doing that's new and it's different, this is the migration.
26:01 Hazel Bohon
In fact, you want this to actually be the first time people are hearing about the fact that you're migrating off of the old platform. You want to be able to show them a success because as I was saying earlier, people often will tell you, "I've been burned before." They've been sold promises before. What we want to be the case is that the first time that they hear about the fact that we're doing a migration is when all of a sudden, oh yeah, your feature's delivered a week early because we're moving over to a new platform that's way better. That way you're selling a success as opposed to promising some future benefit. You have concrete examples that you can give to other people in the organization.
26:38 Hazel Bohon
So at this point, we're probably not actually spending a lot more time on doing the pub/sub aspect of it, right? The pot's been brought to a low boil. We're putting some effort into this, we're putting time and some resources into it, but it's not yet a truly significant investment for us as an organization. What we're trying to do is we're just trying to establish a common base for message passing, consumption, all of those things. As we continue to do this, we're going to build that out and then we will be able to eventually move on to step three.
27:14 Hazel Bohon
Now, step three is where things do start to get more complicated. This where we're going to actually be creating those service boundaries and slicing off chunks of functionality from our original application. We're going to try and define what service boundaries are that we think we want to have, and then we pick one of those services, say, the order placed system. I worked at another organization where we took that approach, right? We decided that, okay, people are able to place orders. We want to be able to take that, bring out of this legacy VB6 code base, and so we pulled that functionality out, isolated from the rest of everything else. When we did this, and that allowed us to focus on just that functionality and created as a separate service. You want to be able to do this one at a time.
28:04 Hazel Bohon
As you do this, you're going to destabilize your system. Pulling out the order submission system from our organization took a lot of effort. It was a complicated piece of code, and there were definitely some bugs as we were working our way through it. We had to take our time with that, and we really weren't able to dedicate ourselves much to any other modernization efforts through it. We were able to get it out, and then we ran into some problems, we corrected those problems over time, re-stabilized our code base.
28:39 Hazel Bohon
You want to go, there's a phrase in off-roading, "As slow as possible, as fast as necessary," and this is the approach that we want to be taking as we're working through this modernization process. We don't want to go too fast. We want to go as fast as we have to in order to get things done, but we want to go slow, because we're definitely treading through unknown territory.
29:03 Hazel Bohon
And we want to be prepared, as I said earlier, to redraw the service boundaries, because there may be things that we discover didn't really belong inside that order placed service. The order placed service, for example, when we broke out our order placed service, pricing information was included inside the order placed system. And we realized later that we actually needed to break that out into its own separate system because that was something that was co-owned by several other services. And so, we created a separate service just for managing pricing information.
29:40 Hazel Bohon
One thing that's very helpful to do at this point when we are pulling out the pieces is to set up a facade, such as following the strangler fig pattern. When we broke out, let's see. So briefly, the way the strangler fig is structured. You start with a client app that connects to the legacy system. What you can then do is you place a facade between the two. So this is basically just a proxy. It will reproduce the existing API and then route that traffic to the legacy system. Now the client app is able to continue to function, there should be no disruption to the client app. Then you add in the new system and have the facade route either to the legacy system or the new system as you add more functionality to the new system. And so in this way, we can create our first service, add it in, and then have the client app still connecting through the facade, able to go to both the legacy system and the new system without anyone noticing on the client side of the application.
30:46 Hazel Bohon
Over time, as we move more and more functionality over into the new system into the discrete services, we'll eventually end up in a situation where the facade simply to access a router, routing over to the new system, and then we can remove the facade and have simply the client app speaking to the new system. After we have gone through this process, created our service boundaries, and isolated functionality into discrete services, we're ready to take on the database.
31:26 Hazel Bohon
The database migration can be one of the most difficult parts. Migrating legacy data is a challenge for organizations and can represent a lot of unique questions. That's why we leave this for last. When we're moving the code base around and we're creating our discrete services, we don't necessarily have as much of a challenge, but for these to really be services, they need to have governance over their own data. And so, each service should have its own database, or NoSQL database, or any other way of storing the information that it needs to store and needs to be responsible for.
32:02 Hazel Bohon
And once you've understood that partitioning of your services, you can think effectively about splitting up that data, and then you can begin by moving things into separate tables, or separate schemas, or separate databases, or even in a separate technologies. The solutions that may be right for one service might not be right for another. It may be the case that you may find that you want to use Elasticsearch in some areas, but you don't necessarily need it in all of the areas. Having the discrete services makes it easier to make these decisions in the places where it makes sense for your organization. And like I said, this has been put off last, because this is going to be an excruciatingly time-consuming portion of the process.
32:46 Hazel Bohon
Wrapping up, change is hard, it is never ending. Software modernization is a process that we can make our way through, provided that we take our time and approach it with caution. And no frogs were harmed in the making of this presentation. Thank you. Do you have any questions? Oh, I also, I will put it in-
33:09 Jay Erdahl
Yay, thank you for not harming the frogs. So we're hoping no... What was it, middle school that we dissected, that we cut into frogs? Is that middle school or high school?
33:23 Elsa Vezino
Probably 10th grade biology.
33:25 Hazel Bohon
Yeah, it was high school for me.
33:28 Jay Erdahl
Okay.
33:30 William Austin
You got one question.
33:33 Hazel Bohon
Oh, sure thing.
33:35 Elsa Vezino
It's from me.
33:39 Jay Erdahl
Oh.
33:39 Elsa Vezino
So, I like the approach about doing it without anybody noticing because it makes it smooth. But because you have a hype man or someone who's talking up as a success, it makes me think that you may be able to do this by having it prioritized with all the other work going on. So I was wondering, based on your experience, how long does it take when you're able to focus on this sort of migration versus how long it might take if you're trying to fit it in so nobody really notices it happens? Just real approximate.
34:23 Hazel Bohon
Yeah, I think that regardless. It depends, right? Always the answer. But I think that for a larger code-based migration, one in which you do have a legacy application that has years of time behind it, it's never done. Right? It will take years regardless to actually do it, even if you do have a chance to focus your efforts on it. And so, I think that that's why it's definitely my recommendation to try to take a more incremental approach, because I think for anything more than a relatively trivial application, doing a complete replacement as a single greenfield project approach is going to take too much time and end up being a thing that will run overdue. Every time I've seen someone try to do one of these projects, it always runs over schedule, it's overdue, or people are burning themselves out working super hard trying to meet a deadline for it.
35:25 Elsa Vezino
Okay, thanks.
35:31 Jay Erdahl
Cool. Any other questions while the recording is going? If not, I will stop the recording so we can have more open conversation. Anyone?
35:43 Cory Maass
Not a question, so much as a comment.
35:45 Jay Erdahl
Yeah.
35:46 Cory Maass
So the company that just killed my product was going through exactly this process, and that was very much the approach that we took, except for we skipped over was it the first two steps and went right to doing it because we had a deadline. It was a mandated course of action from the board that we had to do this, and we had to essentially break down a whole practice management system into component domains, clinical accounting, patient organization, the whole nine yards, in 18 months. Yeah, it was not going well. And it had nothing to do with the process, it was, I mean, the only thing that was going right was we followed a process very similar to this. The execution is where we dropped the ball.
36:37 Jay Erdahl
What's your analogy? How would you describe what you did to the frog in this case by skipping the first two steps?
36:47 Cory Maass
Well, we fried the frog to the plate so we couldn't jump out, is what happened.
36:50 Jay Erdahl
There you go. Not as good. Wild.
36:58 William Austin
I have a comment. I've had the privilege of working with the product from Particular.net, NServiceBus. ILM was involved in it in the past, and I've always found it just so refreshing, I think is the word, to be able to use it. Things just come together so quickly. And a lot of organizations that I've worked with have gone into the, hey, while we're doing this, let's build our own messaging system. It's fun work, it gets people fired up, it's exciting, but it's really hard to get right. So, I've seen organizations bring in NServiceBus and do exactly what you had shown in your diagrams there, and you can get that going very quickly. And it doesn't cost a lot of money, and it doesn't take a lot of time, and you can start showing results very quickly. So, hurrah for NServiceBus.
37:54 Jay Erdahl
Yay. All right. Any other questions for the sake of the recording for future generations? All right, we are stopping the recording.