How to FIX a Spaghetti Code System
10:53
19 сағат бұрын
CRUD APIs are Poor Design
11:20
.NET Framework Migration to .NET 8
10:23
Never rewrite code?
7:02
6 ай бұрын
Пікірлер
@charlesscholton5252
@charlesscholton5252 13 сағат бұрын
Seems like using a callback via a webhook after a message queue reply is picked up, would be a cool way to roll. Provided that end point is part of the message data.
@rafaelmendes6526
@rafaelmendes6526 20 сағат бұрын
Maybe I missed, but Materialized Views are another great way of having read-only tables with non-normalized data
@CodeOpinion
@CodeOpinion 4 сағат бұрын
Yup, I didn't state it explicitly, but that's what I was talking about when talking about a denormalized read model.
@All-in-on-GME
@All-in-on-GME 23 сағат бұрын
Dealing with aggregations in caching scenarios can be difficult to get right or even do at all. If your API allows for many inputs, then caching becomes cumbersome or ineffective due to having to identify and execute on persisting the maximum level to aggregate to as possible without breaking functionality for any of the inputs, but still aggregating enough to make it worth it. I always feel like I should set up caching for these scenarios and then end up realizing it's not the best solution.
@CodeOpinion
@CodeOpinion 3 сағат бұрын
Ya, aggregation can be tricky. Like you said, it doesn't need to be full blown but enough to make it worth it.
@Polychronius
@Polychronius 23 сағат бұрын
For me the hardest part is the concurrent nature of a cache, even worse if it is also distributed. Some day I'll learn TLA+ or such so I can get it... Someday... :)
@midoevil7
@midoevil7 21 сағат бұрын
What is TLA 😅?
@Polychronius
@Polychronius 2 сағат бұрын
@@midoevil7 it stands for "Temporal Logic of Actions", it's math to describe concurrent/distributed stuff basically. TLA+ is a formal specification language that implements TLA. Both are made by Leslie Lamport, the guy who made the Paxos Algorithm, LaTex and other things. There's also a model checker for TLA+ called TLC with which you can find concurrency bugs. It's super neat stuff and Lamport has a great book and video series on it if you're interested! :)
@Polychronius
@Polychronius Сағат бұрын
@@midoevil7 It stands for Temporal Logic Of Actions, it's basically a way to described concurrency/distributed things with math. TLA+ is a formal specification language that implements TLA. Both are created by Leslie Lamport, the guy who created the Paxos algorithm, LaTeX and a bunch of other stuff. He's written a great book and has a equally great video series about it if you are interested. :)
@kagisowilliam982
@kagisowilliam982 Күн бұрын
I had a performance issue about a month ago. Ended up opting for memory caching. The cache expires after a couple of minutes.
@yousef.a.k3793
@yousef.a.k3793 Күн бұрын
Why do you put an IDE thumbnail? I think you're going to show some code to explain your idea every time.
@CodeOpinion
@CodeOpinion 23 сағат бұрын
good point, i'll adjust it
@buriedstpatrick2294
@buriedstpatrick2294 Күн бұрын
In addition to the last part, always measure performance first! Get some metrics from your production environment so you have an objective view of where optimizations are needed so you don't waste time and effort on hypothetical scenarios. It's also very rewarding to see graphs go down after you've deployed something, as a little treat for yourself ;)
@CodeOpinion
@CodeOpinion Күн бұрын
Absolutely
@ba8e
@ba8e Күн бұрын
There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.
@naughtiousmaximus7853
@naughtiousmaximus7853 Күн бұрын
Classic.
@obiwanjacobi
@obiwanjacobi Күн бұрын
@6:17 You really need to watch the pronunciation of 'cache-hit' 😁
@rmbl349
@rmbl349 Күн бұрын
kzbin.info/www/bejne/fHypqYqorMl0jcU this is what I always say to my developers and customers, but most of them don't listen and want that extra work with no benefit.
@mattiasandersson9825
@mattiasandersson9825 Күн бұрын
What can I carve off...? And there you ave your Aggregate root
@Bangotanaya
@Bangotanaya 2 күн бұрын
Hi, this is a great video. Can you share the code that you have been using to debug? Thanks in advance.
@Eirenarch
@Eirenarch 3 күн бұрын
Through the years I've become convinced that it is not an app that owns the database, it is the opposite. The database owns the app (or multiple apps). You take care of the database and evolve the apps accordingly
@tomasprochazka6198
@tomasprochazka6198 3 күн бұрын
Transaction does have a timeout, so for X long message processing, when X > transaction timeout, you must commit twice, and have select a condition on "processing" IS NULL
@DiegoAlvesPereira
@DiegoAlvesPereira 3 күн бұрын
Very helpful video, imma be using it on my next project and it is very good to see a good example of all the theory I've been consuming.
@cicpolk
@cicpolk 3 күн бұрын
Another great video Derek. There are a lot of devs out there not building new things with shiny latest tech, but really dealing with improvements to legacy systems 😊 So videos like this are really helpful.
@lost-prototype
@lost-prototype 4 күн бұрын
I probably can't post a link in comments, but your video titled "Change Data Capture + Event Driven Architecture" at ~2 : 52 is a good one to pair with this! As always Derek, thank you for the great approachable content. Hope one day I can meet you at a conference or similar.
@Jh_1509
@Jh_1509 4 күн бұрын
Another great video, thank you. I work in a warehouse execution system and there is no ownership of data. Inventory, putaway orders, and pick orders for example are modified in multiple services with no concern of ownership or concurrency issues. One service could be cancelling an order while another is picking it and there is no type of concurrency safety in place, I contribute that to what you mention in this video since the writing and reading of data is spread across every service. This makes everything from implementation to testing difficult because you have no idea who owns or changes what data.
@ian2neko
@ian2neko 2 күн бұрын
Maybe implement a status flag? When its waiting for picking, its "Ready" status (allow cancel) when someone "pick" an order, set it to "Picking" (no one can pick again and cancel will need extra internal workflow), when picked order is out for delivery, its "In Transit" (not allowed to cancel).... etc.
@barsenovic
@barsenovic 5 күн бұрын
Focusing on the Use Cases is better.
@stevep5759
@stevep5759 6 күн бұрын
Stealing "6:50 Free for all in the database" :) Finishing up a 200 table ORM jungle with tons of transactions cutting across multi billion row tables with millions of users. Usually I see the database schema is in star or snowflake 3NF when all the user data changes heavily in time together and should be event sourced. I've found looking for a common "fact" table that has a sequential primary key, joining off of that to get to all the "dimension tables", then persisting + reacting to that works great. As a bonus you get exactly once delivery instead of using a persistent message broker.
@CodeOpinion
@CodeOpinion 5 күн бұрын
"200 table ORM Jungle" 😂... I don't think that is that uncommon, hence the video.
@wkuser
@wkuser 6 күн бұрын
Shoutout Detroit
@SanderDecleer
@SanderDecleer 6 күн бұрын
Thanks for this very actionable advice! Everything comes down to managing coupling and encapsulation.
@CodeOpinion
@CodeOpinion 5 күн бұрын
Bingo
@Aalii6
@Aalii6 6 күн бұрын
👍👍
@maxvillafranca3408
@maxvillafranca3408 7 күн бұрын
Why dont you just create a comprehensive tutorial of the most effective patterns and architectures and we all pay handsomly for it.
@CodeOpinion
@CodeOpinion 6 күн бұрын
Maybe....
@AK-vx4dy
@AK-vx4dy 7 күн бұрын
As i here your wise advice i have failed promise of OOP before my eyes, especially missed shoot at encapsulation level - betting on objects more than modules
@essamal-mansouri2689
@essamal-mansouri2689 7 күн бұрын
I'm currently working on a big spaghetti codebase where I'm trying to migrate databases. It does a lot of things including generate reports for that data. And the way I've approached it with this mindset is I'm moving out reporting to a new service. It has basically forced us to implement a way to know when data changes to be able to update the data in the new reporting database. This also means that when I start moving out other parts of the system, I will be able to still have a way to hook into these events and have the data I need to perform whatever it is I need to do. For years this project has struggled because it is too big and being supposedly impossible to refactor without a big bang rewrite but I finally see a light at the end of the tunnel thanks to this pattern. Great advice.
@CodeOpinion
@CodeOpinion 7 күн бұрын
Reporting/Query purposes is often times what is the biggest hurdle. I wanted to mention it more but yes, creating a specialized DB or even creating a schema that resembles the current schema but purely for read purposes is also a strategy, and the segregating the write schemas behind their proper boundaries. At least as a stop gap to keep existing queries working while you transform everything.
@brunosilva-ed4pz
@brunosilva-ed4pz 7 күн бұрын
I work on a 20+ years old shitty laravel codebase without any test and with gigantic, 2k+ lines, files 😅 I doubt we can fix it, even more so with only 3-4 devs on the team 🤣🤣🤣
@CodeOpinion
@CodeOpinion 7 күн бұрын
Ya it's a challenge. You may never get it to where you want, but small incremental changes to isolate functionality and the data behind it can be beneficial.
@ian2neko
@ian2neko 2 күн бұрын
Similar here (not laravel) and change requests keep coming weekly XD.
@funkdefied1
@funkdefied1 7 күн бұрын
I think CRUD caught on because REST caught on, and REST caught on because HTTP won. All the HTTP verbs lend themselves to working on a certain resource, and these resources map pretty well to database objects.
@funkdefied1
@funkdefied1 7 күн бұрын
I love the square peg round hole. It’s been my intuition for a while, but I haven’t heard someone say it. I love thinking about my APIs as actions, RPC style
@CodeOpinion
@CodeOpinion 6 күн бұрын
RPC gets a bad name and I don't really think of it as RPC so much really.
@reginatoronto
@reginatoronto 7 күн бұрын
Super great explanation, this channel is a Gem
@CodeOpinion
@CodeOpinion 7 күн бұрын
Appreciate that, glad you find it helpful!
@marcotroster8247
@marcotroster8247 8 күн бұрын
Usually spaghetti codes are untested systems. So you'd probably write a ton of tests upfront and get to know the domain before you change anything. At least that's how I got started. Interestingly, there's a social component to the problem, too, as if the technical issue wasn't challenging enough. Most likely there's a "senior" coworker who loves ideas like DRY and doesn't understand that it introduces lots of coupling. And also the management has to be technically incompetent because they don't interfere. So you're probably dealing with a lot of incompetent people who won't understand your agenda. It's often hard to pull off a momentum shift such that people trust your judgement. Also the business side needs to be addressed to fix the trust issues between developers and managers. You need to come up with a plan that'll yield measurable results within a few weeks. It's often hard to even identify the problems and figure out how to get started. Usually there isn't any documentation either, so you'll be researching a lot. Once you identified how to tackle the project, set the expectations with management. Usually they don't understand how to work experimentally and go step by step without making big plans. So it can be hard to convey your mission. You'll probably need to do some stuff under the radar to avoid micromanagement. If you can show that you approach works, you'll probably get the ship turned around. Now you have management that trusts you and you begin to understand the system. Tests stabilize the system, so you can finally introduce some refactorings. Now things will accelerate.
@nickniebling
@nickniebling 8 күн бұрын
Great advice! To get management buy-in, focus on other benefits as well. While important to reduce failure rate, it's also great to get better opportunities to e.g. consolidate logic, improve performance, add a cache, add monitoring, modernize tech stack, move from vertical to horizontal scaling (containers?) or whatever you might be eyeing at the same time..
@CodeOpinion
@CodeOpinion 7 күн бұрын
That's a good comment and topic about management buy-in.
@dinov5347
@dinov5347 8 күн бұрын
Timely advice. I currently have.a system where data is duplicated in mongo, maria db, sybase and SAP where the same tables are updated via multiple apps. I am trying to convince management the idea of ownership. Then there is the reporting where they hit a mariadb directly via a third party reporting system (tables with 200+ columns) and I keep telling them to create an API because maria db is failling them and we need to migrate since scaling is an issue. I think they are sick of me in meetings because I keep asking which app should own the data . I think they understand but quite frankly there are so many apps spread out and what I am suggesting will take time just with existing functionality it is virtually impossible to get buy in.
@CodeOpinion
@CodeOpinion 7 күн бұрын
Thanks for the comment. As another commentor mentioned as well, approval/buy-in really is a roadblock beyond technical.
@HELLNAWW
@HELLNAWW 8 күн бұрын
JavaScript
@CodeOpinion
@CodeOpinion 7 күн бұрын
Javascript?
@Al-yg1lt
@Al-yg1lt 8 күн бұрын
Worse than the new "Kurrent" name can only be its new logo (along with the brand color theme). Something strange happened to EventStore brand.
@mattaku9430
@mattaku9430 8 күн бұрын
Would that local cache be in memory only, does it still need to call other microservices in second case?
@MarcelPopescu
@MarcelPopescu 9 күн бұрын
🎯 Key points for quick navigation: 00:00 *🛠️ Derek Martin reflects on 10 years of software architecture, sharing lessons from good and bad decisions made during development.* 00:13 *📈 Understanding industry trends is crucial; staying updated helps inform architectural decisions over time.* 00:27 *⚠️ Using AngularJS for a single-page application (SPA) limited evolution options due to its monolithic nature.* 01:39 *🔄 A good decision was avoiding microservices, opting instead for a well-defined monolithic architecture with clear boundaries.* 02:21 *🗂️ Defining boundaries around business capabilities allows for flexibility and adaptability in evolving the architecture.* 03:30 *📦 It's essential to apply architectural patterns like domain-driven design selectively, based on the context and specific needs.* 04:40 *⚙️ Implementing a web queue worker pattern can help scale applications and manage asynchronous tasks effectively.* 06:12 *🌐 Sharing a codebase for both API and worker processes simplifies development and maintenance.* 08:03 *📩 Event-driven architecture promotes decoupling, allowing independent processes to operate without affecting each other.* 10:24 *🚫 Not all events need to be stored in the same stream; compartmentalizing data improves clarity and utility.* 13:22 *🎯 Best practices in architecture involve defining clear boundaries to facilitate evolution and reduce complexity.* Made with HARPA AI
@bartoszpiasecki8187
@bartoszpiasecki8187 9 күн бұрын
Thank you for your great explanation way data from different microservices can be composed by BFF component and share to client. I was looking it. I would have a other question about duplication data cross different microservice. Let's assume simply scenario for ecommerce solution: Catalog microservice gather products with price. User adds selected product to basket (basket microservice). Should basket item contain price? If let's say in checkout process there is a need to verifiy user limit is exceeded or to sum order price. I imagine basket item contains guid reference to product from catalog bounded context but there is need to keep price too? Or maybe is enough in checkes process sync request (http request) should be done to get price from product context? Regards :)
@CodeOpinion
@CodeOpinion 7 күн бұрын
Well let's say the price is $10, the user adds it to their basket, then you change it to $11. What should the price of the item be when they checkout? There isn't a right or wrong here it's just how you want it to behave. Then based on that you would decide where you want to keep the price.
@stefancovic6493
@stefancovic6493 10 күн бұрын
Great content, watching you for some time now, and I'm not C# developer, but your content really helps! :D How would you represent vehicle in Unhook Trailer action and Dispatch Order? I really didn't understand if those are separate entities in db, or is it just pure logical separation?
@CodeOpinion
@CodeOpinion 7 күн бұрын
Logical separation. It could be physical as well though. You could have them separated in your db. For example, say you were using a relational DB, you could be using the exact same table, but certain columns are owned by certain boundaries. Or they could be separate tables. But it's more logical and how you physically want to separate that is up to you.
@xybersurfer
@xybersurfer 10 күн бұрын
this is terrible advice. the C# type system is not sophisticated enough to stop you from forgetting to check the Error Values (unlike in a lot of Functional languages). no point in pretending that it is (this is not Haskell). it hurts the reliability of your code because you will inevitably forget and that will result in a silent error at runtime, where you would have had an exception. that's an actual "landmine". you have to adapt to the language you are working in 2:51 .NET is full of code that can throw exceptions. you haven't even considered what your code would look like .NET returned an Either type instead of exceptions. it would add unnecessary code churn. most code is not interested in all the specific possible exceptions that can be thrown. most code is only interested in whether something succeeded or failed, in which case the error is reported. Exceptions allow this kind of code (which is the majority), but your solution does not.
@kocokan
@kocokan 10 күн бұрын
sounds very subtle
@frankglynnegrobbelaar2444
@frankglynnegrobbelaar2444 10 күн бұрын
Thank you for the clear & simple explanation!! 👍👍
@yonatandaniyel5640
@yonatandaniyel5640 10 күн бұрын
So many companies think they can go On-Prem and then end up paying top dollar for cloud and system engineers to migrate them to the cloud or struggle maintaining hybrid systems that requires complex networking and expensive integration equipment (like DirectConnect in AWS). Self-hosting is great if you are a massive corporation who has the resources to maintain all the hardware and networking components , as well as the complex software require deep-level system and networking knowledge to maintain them and it is utmost importance to have full control of your data and infrastructure (Think like Top Secret Gov stuff). Not to mention the extra amount of security personnel you will need to protect any type of software behind your own self-managed infrastructure. It is hard enough to keep applications secure on the cloud with a full cloud team , just multiply that many times when hosting everything yourself On-Prem. It's like saying why use higher level software languages that manage your memory and abstract away all the complex algorithms , networking , system drivers, UI code, etc when you could just manage it all yourself. Yes, I get it you have to pay for your cloud infrastructure, but you will also have to pay to run a data center or to lease the equipment in the data center. The more services, portals, consoles, etc the data center provides you the more "cloud-like" they become and then you wonder is it truly better than a true cloud platform?
@iliyan-kulishev
@iliyan-kulishev 10 күн бұрын
I didn't get the first part about having SPA. Are the regrets about not having server rendered pages instead, or using Angular in particular ? I also didn't get the part about "monolith" on the front end.
@CodeOpinion
@CodeOpinion 7 күн бұрын
There isn't anyway to get rid of a large monolithic SPA. To contrast if you have individual pages that are standalone, any given page could be defining its own dependencies (library/framework/etc).
@ErnaSolbergXXX
@ErnaSolbergXXX 11 күн бұрын
I think most of the time micro services is just the wrong solution to a very real problem - you are not able to separate logic in you code and put everything in the same class and make everything dependent on everything. This both applies to angular js and backend code.
@Eirenarch
@Eirenarch 12 күн бұрын
The problem with event driven architecture is not the learning curve it is that it is quite hard to debug. You can't just run your project into the debugger and step through. You need to chase items through queues and through multiple systems. Sometimes it is needed but it is not free.
@CodeOpinion
@CodeOpinion 7 күн бұрын
It is hard and not hard depending on how you physically deploy. This is a great idea for a video!
@AshadeepaDebnath123
@AshadeepaDebnath123 12 күн бұрын
Love this video!!! My best decision was to move to micro- frontend with microservices !
@majormartintibor
@majormartintibor 12 күн бұрын
The best decision I made and am constantly making is to spend time outside of my regular work hours to read and learn. Countless times I was sitting there at either 23 in the evening or 5 in the morning reading a blog or book, watching a YT video or listening to a podcast and getting the moment of realization: "oh, this would have solved my problem back then", or "this is exactly what we did wrong, now I understand why it was a mistake" etc. Never stop learning.
@CodeOpinion
@CodeOpinion 7 күн бұрын
"ah-ha!" moments are great.
@aslkdjfzxcv9779
@aslkdjfzxcv9779 12 күн бұрын
monoliths. yuck.
@twstdp1
@twstdp1 13 күн бұрын
Amen to this! It just creates spaghetti. My least favorite is when people extract methods and name it something like "DoXAndDoYIfCondition". SRP gets lost on these people and they might as well just not make a separate method at all. And as you say this is especially important when throwing exceptions. I should be able to see from a parent level exactly what exceptions will get thrown for certain conditions not dive 5 methods deep to find it.