...

Analyzing Architecture Tradeoffs

Originally aired:

About the Session

In their latest book “Fundamentals of Software Architecture” (O’Reilly, 2020) Mark Richards and Neal Ford coin the first law of software architecture: “Everything in software architecture is a tradeoff”. In that case, how do you analyze tradeoffs and make a decision? As Mark Richards states, “Architecture is the stuff you can’t google”. In this session Mark Richards guides you through how to effectively analyze architecture tradeoffs through numerous real-world scenarios involving architecture tradeoffs.

Transcript

Hello, everyone. Welcome to the session. Thanks. I, you know, it's so funny, in today's world of virtual conferences and stuff everybody gets to see my office. So anyways, yes. All right, but you should see my desk though. It's... it's not as clean as my bookshelves are.

Fantastic. I think if I'm not mistaken, this is the last evening I'm guessing, but, I will be back tomorrow morning. You know what, yes. I have read every one of those books that is one of about, I think. I had the guests probably about, at least 12, if not 15 bookcases, in my house. And so anyways, but that's, that's the only one that will actually fit in my office.

So, all right. So, you know what I want to talk about in this session, I was really about analyzing architecture, tradeoffs. That's one of the things an architect actually has to do, and I want to show you some techniques for being able to, to determine, the tradeoffs and, and stuff. So anyways, I'm really excited for this session here, it's, as a matter of fact a brand new one. This is brand new material that I put together specifically for GIDS. I'm really anxious to try this. Oh, I know it must be so frustrating that there's all these great sessions in parallel. I'm assuming all of you can kind of hop in and out of different sessions.

I can't, unfortunately I have to stay at this one because I'm speaking. All right. It is really, it must be so hard to choose. Yeah. exactly. So, Oh, right. Well, let's actually dive in and take a look at it. Basically analyzing tradeoffs. You get over to my other screen here and see how to, there we go.

Okay, fantastic. So, Neil Ford and I wrote a book fundamentals of software architecture. I think I've got it. And as a matter of fact rights. Here it is in my bookshelf, the actual physical copy of it.

In this book, we actually quoted several laws of software architecture as a matter of fact, the first law of software architecture that Neil and I quoted in our book is that everything in software architecture is a tradeoff, and if that's the case, this is where we get to the "it depends". Well, should I use A or B? Well, it depends. As a matter of fact, also in the book is my famous quote about architecture, which is, architecture is the stuff you can't Google.

And, unfortunately we can Google a lot of things, but we can't Google a choice between A or B. And that's what I want to show you in this session, how to actually make that distinguishing factor.

So, if everything in software architecture is a tradeoff, then how do we make a decision? And so, that really kind of points to the second law of software architecture that we quoted in the book, and the second law is that the why is more important than how, and this was one of my epiphanies in software architecture back in 2011, as a matter of fact, when I finally realized, you know, I've been spending way too much time describing things in architecture, but what people really want to know is, wait, why did you actually make that decision?

And so these two laws really do go together because when we analyze tradeoffs and make a decision. Necessarily the second law of software architecture applies, which is "yeah, but why did you make that choice?" And so that's what I want to analyze in this session.

So when we analyze architectural tradeoffs, we cannot, or I should say, I shouldn't say we cannot, it's really, really hard to make a decision on A or B, and we're going to look at multiple scenarios in this session without first understanding the business drivers.

In other words, that gives us the grounding to make an architectural decision. And from there, then we're able to actually get, or form those ilities, performance availability, reliability.

That's what ends up driving our architecture decisions, and analyzing tradeoffs. And so, we're going to go through a lot of different scenarios here, in terms of technology as well as how to make a decision about something.

So for example, if time to market is the most important thing to business, And that means, speed to market is another term for this, what that equates to is the fact that I, as an architect, I need to translate that to the corresponding ilities are what I call architecture characteristics. For example, maintainability, testability, and deployability are going to be the most important things in that architecture. That's what's going to end up driving a choice between, maybe using synchronous or asynchronous, for example. So, with this in mind, with this in mind...

Oh, yeah. So is it possible to relate to SES ATAM? Yeah, so, I don't talk about ATAM or CBAM in here, but I absolutely will. This is what I love about questions. Yeah, so ATAM, Architecture Tradeoff Analysis Method. This relates to it in a way; ATAM is a process by which, it's an older process now. Now has gotten some agile teeth to it now, but, ATAM is kind of a process where, you bring an architecture to stakeholders and, it's kind of a formal process where you described the architecture, the stakeholders fire off different scenarios to you, and you kind of justify those through the architecture.

The spirit of ATAM is very much alive. The process doesn't work very well. It's not agile enough. Now, of late, there's two, there used to be two methods ATAM and CBAM, Cost Benefit Analysis Method. So, instead of looking at a tradeoff between availability and performance, very similar to things like CAP theorem, you know, pick two out of, whether you want Consistency, Availability or network Partitioning, you can't have all three.

And these are the kinds of conversations we end up with with tradeoffs. And so CBAM is a method, a cost benefit analysis method where we say, well, how much is that going to cost me?

Of late, these two methods really are now bridged together so that while we're analyzing availability versus performance, In that equation now is yeah, but what about cost? You know, does that factor into it? And so all three of those things are now kind of combined together, but, yeah, the stuff I'm going to go through is very similar to, the ATAM process.

And so let's go through an example, because I want to show you four different examples or four different layers, and we're going to actually do an exercise in here as well.

So, suppose you have a software developer who says, "You know, we can reduce our latency for service calls from 110 milliseconds round trip to seven by using GRPC", and that's actually true. Hmm.

So here's the question. Should you use it then? I mean, so this is a good example of what an architect might face in terms of having to approve a certain protocol, for example. Hmm. Well, I don't know. Let's Google it.

You can't Google it. Should you use it or not? Let me show you how we would arrive at a decision to say yes or no.

So, Google's remote procedure call. It is a remote procedure call, very, veryfast, and as a matter of fact, it can reduce from 110 down to seven milliseconds of latency in the network traffic. That's huge, over 10 times. Let's apply our first law of software architecture. The first law of SaaS software architecture states "Everything has a tradeoff."

As a matter of fact, the first corollary to the first law of software architecture says "If you haven't found it, if you don't see that there's a tradeoff, it just simply means you haven't found it yet."

So, I have a developer telling me through research, "Yup, you can get 10 times improvement in network latency over best." And this developer demonstrates 110 milliseconds down to seven.

An architect would say, "Okay. Let's apply the first law of software architecture. 'Everything has a tradeoff'. So what is the tradeoff? Ooh, well, it is a remote procedure call, so we do have client server stubs, which means there is a tight coupling between those two services.

If one service isn't available, the other service is not operational. This is a remote procedure call. So I've got tight coupling. I own a piece of your code. You're giving me a piece of your code that I can execute. And then behind the scenes, it's doing all the remote calls and stuff. So there's our tradeoff.

So, let's apply this. Performance versus maintainability. So what we come up with is this. Okay, 10 times improvement, but tight coupling. So what does this really boil down to from an ilities perspective? It's a tradeoff between performance and maintainability. Ah, so it's faster, but I've got tightly coupled services; harder to maintain those now.

So, let's apply the second law of software architecture. Which states that "The why is more important than the how" so applying the why piece, we say, well, wait a minute, let's go back to the first start of the session. What's important to the business? Time to market, that is the most important thing.

I mean, when we have a new feature or a bug fix, we need to get it out to our customers as fast as possible. That's the most important thing to us. Ah, so, what's that translate into? The fact that I, as the architect, want to say, "No, we won't use Google's from a procedure called GRPC." It's like, "Wait, why?"

Why! There's the why piece! "Oh, Mark said no." "Well, that's silly." No, it's not watching this. No, because maintainability is more important to us than performance, because it goes all the way back to understanding those business drivers. It's all about time to market and that's more important than having that latency reduced.

And so you see. All these are decisions we have to make as an architect. And the point is we go back to, what is the grounding force? What is, what is the driving force behind all this? In fact, it is time to market. And so that's how I would arrive at "No, we won't use it because maintainability is more important to us than performance because time to market is what the business is really driving after, not super high performance."

Alright, now, there's other techniques that we can actually use to analyze architecture tradeoffs. For example, here's a hard one. Software architect says this, "I wonder if we should use a single payment service for all of our payment processing: credit card; PayPal; Venmo; gift cards. Or should I have a separate service for each of those?"

You know, service granularity is really, really hard, but this kind of decisions, all of a sudden it's like, "Well, I don't know. I mean, flip a coin I guess, or something." Ah, so another way to analyze tradeoffs is what I call a scenario driven approach.

And so in other words, when we start analyzing the technology, we can go and have all these discussions, but what we can do here is actually draw out some scenarios to help us make the decision, because what does this boil down to, really? I don't know. So let's actually walk through it, watch this.

Let's do a scenario driven approach to tease out what the tradeoffs really are, so that we can make a difference in say a or B because you see here's the problem.

I can't go to a product owner and say, "So I need some help here. Should we have one service or three services?" "Whoa, I don't know. You're the architect." I'm like, "Oh, great." So, first law software architecture, "Everything is a tradeoff", so let's tease out those tradeoffs through scenarios. Let's do our first scenario.

Well, I don't know how to make this decision, so let's do some scenarios here. How about, if I wanted to update the credit card processing. Now, how would that work with both of these? This is almost like a form of modeling in a way.

Well, let's see, on the larger service, I would have to make changes to the core, you know, table that is shared by everybody as well as that. So the problem is I'm going to have to test and probably retest that entire service. So my testing scope is significantly higher and when I deploy, I have to redeploy that entire service, whereas on a separate service, watch this, I just make changes to the credit card service. That's what I test and deploy. I don't have to do anything to PayPal or gift cards.

And so the point is my deployment risk is much lower. My testing scope is lower. And as a matter of fact, that's a pretty fast change. And so, clearly, separate services is the better choice here, but let's keep going on different scenarios.

Yeah. So what if you want it to do this: What about adding a new payment type? What if I wanted to add reward points? So we're going to start accumulating reward points. Ah, okay. So, let's do that. So, on the left hand service, I added reward points. What do I have to do? Well, I have to add that code and also change the data again.

It's like, wow, even if I add something, I still have to retest that whole service. Did I break anything with PayPal or credit cards? I don't think so. So now, all of a sudden it's going to take [inaudible 00:14:54] to apply this change because I have to test more and my deployment risk again is higher, but watch what I do on the right hand side.

If I've got these payment types of separate, all I have to do is create a new microservice or create a new service called rewards points service, add the code, add the data, put it in a container and deploy it. And so the point is I'm not even touching any of the other payment types. As a matter of fact, as I'm deploying that we can charge a credit card or PayPal.

And so, clearly, you can start to see the fact that we should probably go with separate services. But is there another scenario here? There is, because the other scenario is, "Oh, but wait a minute, people, customers can use multiple payment types to pay for an order. In other words, I want to add this to my credit card, I want to use whatever store credit I have, I want to use my reward points and I want to put half of that on PayPal", ooh.

So, what will we have to do on the left hand side? Not much. I mean, we had a class file to basically invoke multiple methods, and then the point is, since it's all in the same database, I've got commits and rollbacks, but what would I have to do on the right hand side?

You see on the right hand side, I would have to add a payment orchestrator, any ENT I'd have to have all sorts of complex logic right there in that payment orchestrator. And because now everything would have to come through that payment orchestrator, so I'd have to reroute all of my restful API calls from a service discovery standpoint to point to that payment orchestrator, but worse, "Ooh, I would have to have all sorts of complex rollback logic. What if I apply a credit card that gets committed, I go to do it gift card and that service isn't available." All of a sudden it's like, now what do I do? I'd have to roll back that credit card piece, but I already charged PayPal as well.

And so the point is there's a lot of complex error handling logic as well as data inconsistencies. And so here, it's like, "Oh... yeah, separate services is not such a good idea in that case."

So you see, through driving out these scenarios, what we actually have is now an ultimate tradeoff performance and data consistency, because don't forget also that, as a matter of fact, I want to go back one here.

The other thing is the customer is waiting for this and I have now added more network latency because you can guarantee it's not only network latency. It's also security, because I'm guessing all of those end points, those services obviously have to be reauthorized. I'm hoping, because that's all financial stuff, and so I probably got about a half a second on each one of those calls, separate from the error handling logic.

So the point is, what it really boils down to is that performance and data consistency versus maintainability, testability, and deployability. In other words, the ability to respond quickly to change.

Now, through driving out these scenarios, now I can go to the business stakeholder or the product owner and say, by the way, I've got a choice, one service or three. So here's the question for you though, "Which is more important for you? Performance and data consistency or ease of maintenance, pick one."

So the scenario driven approach from a domain driven approach. So , it's more about a domain-driven approach is actually looking at the functionality. So, not a lot of the scenario driven approach really focuses on driving out or teasing out these two things, maintainability versus performance.

Through driving out scenarios, I can reverse this and say, "Well, what do you mean, maintainability?" I can reverse that and say, "Well, suppose that I add a new rewards points, or suppose I do this", those are scenarios.

So that's where it really differs from a domain driven kind of design, That's where we're starting to tease out things that we may or may not do, as a matter of fact. So the fact of domain driven design is going to really talk about the functionality of these versus the actions taken on those.

So that's where, you know, and scalability might also be a good tradeoff factor as a matter of fact. Yeah, so, another one. It's going to be much easier to scale our credit card service as opposed to our entire payment service. And that's a good point as such.

My point of this technique is really, to try to have those intelligent discussions. As an ultimate "Well, give me the bottom line." When we're talking about A or B, what does it really boil down to? Well, the maintainability, in other words, the ability to respond quickly to change, I can get changes done faster, but it's going to be slower to the customer, which one is more important?

And then we can start to analyze, well, how much change would we actually have? And so it's one way of actually, arriving at a point for a tradeoff.

Another technique that you can also use is to basically take these kinds of scenarios from a technical to a business approach. So watch this one here. This is kind of an interesting, this is a real scenario, but this is also how to kind of analyze these tradeoffs to be able to make a decision. [inaudible 00:21:37] a software architect and that software architect says, "I can't decide if I should use synchronous or asynchronous communication to kick off our credit card application process once I accept the application and complete and validate it from the customer."

I don't know, let me actually describe this for you. Okay. So here's our application service. So if we're going to apply for a new credit card, the customer fills out the application online and hits the submit button, the application service, which is our customer facing service, highly scalable fault tolerance, always available, blah, blah, blah, receives that application, validates it. And then generates an application ID and sends it back up to the customer and says, "Got it."

Now there's three other things that happen in this credit card process behind the scenes afterwards. We'll eventually send that over to get a credit check. And so we're going to look at your credit history and stuff, and then there's an approval service, which does an approval process, to determine are you approved and how much your credit limit is going to be and stuff, and then an account service, which then creates a new account along with a new credit card, and that's all orchestrated through a service that mediates that whole process.

That's what the workflow is owned by, that new application service, and that's where the status is. All right. So, clearly, once I have the application in hand from the customer, I need to kick off that process.

How do I communicate to that microservice there? That orchestrator. I could use synchronous calls, for example, using something like rest. Or I could use asynchronous maybe using messaging. Which do you think we should do, synchronous or asynchronous?

Alright, so Jersey likes event driven, which is the asynchronous. Yeah, async seems to be. Yeah. How do you make that choice? I mean, wait a minute. This is like a technical choice, isn't it? So how? So, I like the fact that a lot of you like async, I like async as well, but, why? Ah, so Meghana is starting to get to the bottom line here. Yes. It's about being reactive. It's going to be a lot faster, right away.

Scalability. Yup. Exactly. So we've got scalability piece, responsive. Yeah. Resilience. The credit check might take time. So yeah. So the point is the customer is not waiting for this. So keep in mind, the application service has already sent back the- to the customer and said, "Here's your application ID, we'll get hold of you later on."

So all the stuff you see with that orchestration with the credit check approval is all being done afterwards. The customer's not waiting for that. I mean, that could take anywhere from five minutes to two days, you know, it depends.

So yeah, it's, post-processing exactly. yeah, it's post-processing. So you're the architect. How do you make this kind of decision? So it does. So this is, I love this. So we're starting to tease out, a lot of you like the event driven async, but here's the question, the second law of software architecture. Why? What's your justification for that?

So how do you make these kinds of-? I got an idea. Let's Google it!

This is what I mean, this is architecture. I mean, we can't Google this to say which should I use, and this is one out of dozens of decisions I may have to make today.

So yeah, so Schrader likes this because it's faster responsiveness. It can become a sync call, but the user doesn't have to wait. So generally, if the user is waiting, which the user is not in this case, but maybe they are, the point is, if I kick off that process, yeah, one of the factors is, yeah, but we always want to think about responsiveness. So now we've got one side of the tradeoff, don't we? Yeah, the customer experience.

So sounds to me like asynchronous is probably a good choice. However, watch what happens here. So, how do you make this kind of decision? Check this out. First law of software architecture is "Everything is a tradeoff."

So let's do a couple of observations. Let me move my little mouse here. So, exactly, so Sridhar, and a lot of other folks. Yeah. Observation number one. Well, async is more responsive than sync, so one of the techniques in analyzing tradeoffs is start to write these things down. And so let's start writing down our observations. Well, async is more responsive than sync. In other words, the customer's waiting for this end to end; the customer's not waiting for the credit check and the approval.

The customer is waiting for the application ID to be sent after the submitting and for the process to get kicked off. Okay. So it is more responsive because now the customer doesn't have to wait, but I like VJs response here though: Fault tolerance and resiliency, ooh, versus maintenance. Huh.

Maybe so, because here's the thing: if I did synchronous calls, this does in fact guarantee that that process will start, doesn't it? In other words, it's going to take a little longer because the customer has to wait for that synchronous call, but it does guarantee that the orchestrator does receive the kickoff of that whole process; async doesn't guarantee that.

Now you might think, "Oh, nope, nope. We can do guaranteed message, guaranteed delivery", but you know, if there's something wrong with that message. and the orchestrator rejects it, it's eventually going to go to a dead letter queue. And so the point is there's no real guarantee. I could lose that application.

However, observation number three means this though: if I did a synchronous call, that means we'll reject an application if the orchestrator is down. So, somebody talked about fault tolerance here. Yeah, exactly.

So what happens if I say, "Oh, no synchronous call", but what happens if the orchestrator is down or it times out? What do I do now? I can't accept that application. And so the point is that I'm going to have to go back to the customer and say, "Sorry. The application submit failed because the orchestrator's down", ah, but async guarantees that I don't have to wait for the orchestrator. And so you see if we look at these observations now, what do you think?

So Sachin is saying that message retry guarantee should be done at least once. Generally, it's done 7 to 10 times. The broker will continue to send that message over to that orchestrator. If the orchestrator rejects it, it continues to try. This is a configuration setting in most brokers, but generally it was around 7 to 10 times, depending on the broker. And finally it tags it as a poison message and we'll send it to a dead letter queue or, you know, something similar.

So, what do you suppose, if we're going to try to tease this out right here, what do you suppose this tradeoff is really boiling down to here? Anybody kind of see, based on these observations, Narash is saying we can have a hybrid solution; application ID could be reactive, API and rest for all the event driven, orchestrator can keep track of the vet processing status. That's exactly my Mirage. The key point is, though, that you see what this is really boiling down to. Yeah, it's, consistency versus availability. Yeah. That's really what it kind of boils down to because, watch this.

So if we actually, here we go. Let's see what it boils down to. What it boils down to is not actually an issue of performance. I mean, that's what we started on. We started on the issue of, well, responsiveness, but here's what it really boils down to.

If I do synchronous calls on the left hand side, the application process, in other words, to kick it off is guaranteed to be started because that's synchronous. I can't accept an application unless I'm guaranteed that the orchestrator has that application and is starting that process, but the point, is if that orchestrator is not available, I can't accept the application.

On the left hand instead of the right hand side, the application can always be submitted, because I'm just sending it to a queue, but there's a chance I might drop a particular application.

It could get lost, because there's no guarantee the orchestrator will get it. Like, we have a lost message. And you know, this really boils down to two things that I can actually talk to a business stakeholder about. Here's the thing. It's not about responsiveness, everybody, it's about this: do we always need to be able to accept an application regardless? Or do you want to guarantee that the application process is started?

It's exactly, by the way, somebody said, Oh, Meghana, can CAP theorem also be considered? Well, it is like CAP theorem. We can always guarantee to accept an application, or we can guarantee that the application process will be started and we won't lose a message. Pick one.

Yeah, we can't do both. And so isn't it interesting that what this really boils down to is turning a technical decision of async versus sink into a business question, which is really about which do you want to do in this application? Which is more important to possibly reject a submission for an application or always available.

Now, and so that's what it really boils down to. Yeah. So VJ. yeah, so there are things that we can actually do. So to guarantee the application process is started, we can actually apply something called the workflow event pattern. As a matter of fact, let me, in lessons, cause I don't want to take too much time here.

It's towards the bottom, but if you go to, I'm going to send all of you a link in here. There it is. So on my website, developertoarchitect.com/lessons, you will see a lesson towards the bottom and it's called "The Workflow Event Pattern". I think it's like lesson maybe 50 or 60, but VJ, that's what we can actually use, to maybe have a hybrid to guarantee that the application process would be started. It's a way of saying, if it goes to a dead letter queue, it goes to something called a workflow queue, which then tries to resubmit it. If it can't, it sends it over to a human. So at least it's not just disappearing. Yeah. And that might be a way of trying to guarantee that the process has started and keep that resiliency.

Yeah. So good point. about that, but the illustration really here is a technique more so than getting into the details of this example, which really is kind of stating we went from, should it be async to sync, to a question about the behavior of the application? So that's really the point of that.

Let me just go back over to here. Alright. Exactly. So, I'll be showing you one more because I'm going to actually have all of you do this one as an exercise. So, let's say that we've got an auction site here and we're doing bids, producers sending an item bid. So I just bid for an item. That bid, it has to go to three places: it has to go to a bid capture service. a bid tracking service and a bid analytics. Yeah, like eBay or, yeah, eBay. Let's say it's eBay. I liked that. I liked that a bit.

So here's the question. You're an architect. We could use queues on point to point messaging so that the big capture tracking and analytics all have the corresponding cue and the producer sends that to all three of those queues, or... a topic in a publish and subscribe fashion, where the producer only sends one message to a single topic, and then the capture tracking and analytics all read from that topic as subscribers. And so the real question is this, and observe here, the producer only has one. Destination, whereas here, the producer has three destinations. It needs to go to three different cubes to send those.

So the question is this: Which one would you prefer? Queues or topics? You have to pick one. So what I'd like everybody to do is this, Kind of look at this and analyze it, and a lot of people like option two. Yeah. Clearly. Wow. Ah, so, right. This is what I'm wanting.

Okay. But why? Don't forget that second law. So there's two laws of software architecture that come into play here. So extensibility. So, Shona. Yes. So, option two because of extensibility, but why don't we take a couple of minutes here and, you know, if you got a pencil and paper, that'd be great, or if you've got maybe a notepad or something on a computer, but, let's actually apply some of this stuff, apply the first law and think, well, before kind of arriving at a choice really quick, what are the tradeoffs of each? And then, boil it down to what's most important. And let's see if we can do that.

So let's take a couple of minutes everybody, and really kind of think about what are the tradeoffs and why.

Ah, so Rohit makes a really good point. Hey Rohit, how are you doing? I thought you were in a session. Yeah. So Rohit saying we also need to consider, out of the three services, all three might be consuming at a different rate. So again, there's consideration. So we saw three different techniques of teasing out what the tradeoffs are, scenarios, we saw kind of turning the technology into business.

You don't have the business context. However, what I'd like you to arrive at is what would the discussion be with your product owner, and it can't be queues or topics. That's the trick about analyzing tradeoffs. We take it from the technical and move it into a business choice. And so I want to see if any of you can, so let's spend a little bit of time.

So what I want all of you to eventually arrive at is A versus B. In other words, what is this... now, it might not be one, it might be two or three considerations, but what are the real considerations here? Ah, so we've got a couple coming up here. If all three needed to consume all message, then it will be redundant and option one.

Yeah. So we've got, we've got a little redundancy here. Yeah. So, think about this in terms of ilities. So we already have one ility so, Shogun. I, Raj had said there's one extensibility. And so extensibility is much better than option two than it is in one, but what's better about one than two?

So I like that. So Cool says, isn't it similar to a prior example of different payments? It kind of is. Yeah, and we saw the payment one, really boiled down to ilities. we took it from one to three services and we boiled down into an issue of maintainability versus data integrity. And there's the same kind of thing here.

There's ilities that we can compare against here. Ah, so availability of the producer is going to kind of be on both a vendor it's really going to be too. So yup. Independent, ah, so now we're getting somewhere on it. Yeah. Independent reconciliation, higher bandwidth and option one. Yeah. So that's interesting.

You're right. Alone. That's a really good observation. We've got a lot more network traffic happening in option one, don’t we, than option two with the pub sub. Yeah.

Yup. better extensibility and topics are better maintainable. Yup, exactly. Ah, data redundancy is in option one. Yeah, we've gotten more data. So, What's the point about option one, take, let me take a look and let me show you here. The first law of software architecture, tradeoffs, what are the tradeoffs between these, let's actually analyze that because I think you've got most of these.

So here though. Looks like everybody liked option two. The extensibility is great, but look at option one. Each big capture tracking and analytics can have its own contract, but in option two there's only one contract. It's one message, which means that that's a uniform contract. Now that may be good or bad.

I don't know. Now I've got to analyze and say, well, what kind of information does bid capture, bid tracking and bid analytics need? Cause bid capture only needs the bid, but then tracking may need all sorts of other information. Analytics may need the prior three bids. So, point is, that may be fine or may not, but that's one of the considerations.

How about security and access to that data? What, in pub sub here that topic, can anybody access that topic? And the answer's yeah. So I don't really have control over who's going to read that data, but in option one I do, because I'm explicitly sending it to a queue and point to point, which means only one receiver can receive that message. Now, I can load balance that, obviously, but bid capture can only read from the bid capture queue. If anybody else does, the message will get lost. And so that's another consideration. And then the third is this: queues. I can do auto-scaling. So, Rohit had said, "yeah, but these might be absorbed at different rates and stuff."

So I can do monitoring of a queue depth number of messages waiting, and I can auto scale the capture tracking and analytics. I cannot do that with a topic. So there's no way of getting the cue depth of a topic, which means I don't have auto-scaling capability of the bid capture tracking and analytics.

However, over on this side, a good catch on that extensibility. Oh, if I wanted to add bid history, go ahead and just add it, you know, just add it and subscribe to the topic. There are no changes at all to the producer. However, on the other side, Yeah. If I added a bid history, I'd have to add a new queue and I'd have to modify the producer, therefore having to test and deploy that service.

And so, yeah, that's, what architectural extensibility is all about and service decoupling. See, on the left-hand side, on the queues, the producer needs to know to send it to all three. It has that knowledge, but on the right-hand side, the producer has no knowledge about how that bid data is going to be used.

Totally decoupled. Yeah. So queue depth of a topic for AMQ P can still be monitored. so through an advisory topic, Meghana, I can find out which subscriber has not still received that, but the problem is bid capture and may have already received that as a subscriber, but the tracking may not have.

So yeah. so that might be and, it depends, exactly. As a matter of fact, with RabbitMQ, I can't monitor the exchange in a zero.nine.one, which is what most use, not one dot O, however, one dot O, I can, because the exchange is actually implemented as a queue, as opposed to kind of a virtual topic.

So yeah, that last piece about auto-scaling is a consideration, but now I can say, but yeah, but we can do that, although it's hard, but we can do that, depending on the technology.

So now we can see what it actually boils down to. Which is more important: extensibility and decoupling, or to be able to have different kinds of contracts and security control?

And now I can say, well, these are bids, so it doesn't really matter. However, if this were a trade, then it would matter. Or if it were a credit card process, it would matter about who can access that information. So my point is, this is what it tends to boil down to are these kinds of analysis pieces that now we can start plugging in and saying, well, how can we deal with the auto-scaling because that we do need, and you're right. That may do a choice of a particular type of technology, for example. So, excellent.

Conclusion

Well, so this is hard, analyzing all these tradeoffs. We saw a couple of techniques, but really what it boils down to, everybody, is needing to have the business drivers in hand; identifying those first, and what's really important to the business drives those ilities.

And once we have the ilities at hand that are important to us, like performance versus maintainability. Then, we can do the analysis, make our choice and then have that second layer of software architecture, which is the why piece. So, yeah. Excellent. So, the decisions vary for different message products.

Exactly. They got on it. And so knowing the tradeoffs and knowing. And the situation will then drive to say, well, but we're using ActiveMQ and we can't have that, we don't have access to the advisory topic, for example. Or we're using HornetQ, which doesn't have that advisory topic.

So, that would be a limitation that the choice of technology has placed on a need for auto-scaling because we choose to use topics. Yeah. So my point is, Meghana, yes, the decision to use varying brokers may be driven by that architectural analysis that we just did. So, excellent.

This is hard stuff, everyone. Trying to tease out what are the real concerns out of choices we make in architecture, is what these techniques are all about, but you've got four really good ones here that looked at just to kind of start exercising, this kind of tradeoff analysis and really diving deep. It's a trying to find out what is the tradeoff.

And again, if you haven't, if you've come up with anything that you can show me to say "Mark, I found something that doesn't have a tradeoff." Nope. It just means you haven't found it yet. And that deep research is how we usually uncover some of those things. So, all right. Fantastic. Well, I'm going to let all of you go.

I believe that you all have had a long day, but, I will, hopefully see some of you tomorrow. I'm going to be actually teaching The Fundamentals of Software Architecture, and that is your tomorrow. It's my tonight. It's very weird. You all get to sleep when I'm here awake. but I will be back in this seat my evening, your morning, for that workshop.

So anyways, so hopefully that gave you some insights into ways of teasing out these tradeoffs and stuff. So, fantastic. Stay safe, everybody. Have a good evening and, be all rested up for GIDS tomorrow morning, so alright, goodbye everyone.

See Highlights of
Wurreka

Hear What Attendees Say

“Once again Wurreka has knocked it out of the park with interesting speakers, engaging content and challenging ideas. No jetlag fog at all, which counts for how interesting the whole thing was."

Cybersecurity Lead, PwC

“Very much looking forward to next year. I will be keeping my eye out for the date so I can make sure I lock it in my calendar"

Software Engineering Specialist, Intuit

“Best conference I have ever been to with lots of insights and information on next generation technologies and those that are the need of the hour."

Software Architect, GroupOn

Hear What Speakers & Sponsors Say

“Happy to meet everyone who came from near and far. Glad to know you've discovered some great lessons here, and glad you joined us for all the discoveries great and small."

Scott Davis, Web Architect & Principal Engineer, ThoughtWorks

“What a buzz! The events have been instrumental in bringing the whole software community together. There has been something for everyone from developers to architects to business to vendors. Thanks everyone!"

Voltaire Yap, Global Events Manager, Oracle Corp.

“Wonderful set of conferences, well organized, fantastic speakers, and an amazingly interactive set of audience. Thanks for having me at the events!"

Dr. Venkat Subramaniam, Founder - Agile Developer Inc.