4 ms·
For me the big takeaway is this: Refactoring across the call stack is orders of magnitude easier than refactoring across a socket. Sacrificial or not, you can
by ecoffey 11y ago
For me the big takeaway is this:
Refactoring across the call stack is orders of magnitude easier than refactoring across a socket.
Sacrificial or not, you can still write the Monolith as "Service Oriented", just that boundary is the call stack. Especially if you're comfortable with IoC and DI.
Building on the latter I've had success with that. Stubbing out hardcoded concepts that I know will come from a as-yet-unwritten service in the future. Then you start pushing those hardcoded things "down and out"; e.g. it was hardcoded in App A, but now App A requests it from App B, but App B just has the hardcoded thing.
- twerquie 11y ago> Refactoring across the call stack is orders of magnitude easier than refactoring across a socket. That's assuming that things haven't become deeply coupled within the "call stack". Separating things across a socket often forces a separation of concerns, which does tend to make refactoring easier.
- ecoffey 11y ago> That's assuming that things haven't become deeply coupled within the "call stack". Yep; Monolith or SOA you still have to write SOLID code :) > Separating things across a socket often forces a separation of concerns, which does tend to make refactoring easier. It /should/, and if it does now your changing more than the one variable of "invoked across stacks -> invoked across socket", and are more likely to introduce a regression :)
- crdoconnor 11y ago>Separating things across a socket often forces a separation of concerns It doesn't really force it. It just makes life really difficult for you if you don't. That doesn't mean it happens, though.
- bad_user 11y agoIn my experience communications across a socket does not force a separation of concerns. It doesn't even encourage it. Heck, because asynchronous communication in a non-deterministic environment is so hard to deal with, my experience is that such communications encourage shortcuts to be taken, so yes, I think it encourages tight coupling. The only thing that somewhat encourages a separation is having different people responsible for different modules and because people are selfish, they'll fight for their components to have less responsibilities, not more. So it becomes a territorial thing. But this happens only if you have seniors that know what they are doing, otherwise rookies or less competent folks end up cooperating to "get things done".
- AnonJ 11y agoWeird reasoning, that. I hardly see how a selfish, "territorial" and noncooperative approach could benefit anybody. Sure people might cooperate, but that doesn't mean they will take shortcuts and mess things up.
- nickbauman 11y agoThis is why AppEngine modules are so awesome. Have a route that takes on the majority of your traffic? Slice it off the main app declaritavely to its own cluster of machines.
- dasil003 11y ago> Refactoring across the call stack is orders of magnitude easier than refactoring across a socket. Yes. > Sacrificial or not, you can still write the Monolith as "Service Oriented", just that boundary is the call stack. Or just "modular". Obviously you should always make things as modular as you can, but at some point there are irreducible logical dependencies where increased modularity decreases cohesion more than it helps anything else. Certainly it's a good to strive for the ideal, but at the end of the day a "service-oriented" monolith is not going to enforce the architecture the way a true SoA will. It's sort of like Haskell's purity guarantee—you can write functional code in a lot of languages, but the benefits you reap from having a compiler's guarantee of a certain code's purity is an order of magnitude more useful than browbeating a team of cats to always follow the style guide, because no matter how good your training your "guarantee" is always subject to human error.
- joeyespo 11y ago> at the end of the day a "service-oriented" monolith is not going to enforce the architecture the way a true SoA will This is true. However, even with that enforcement, those guarantees don't prevent you from implementing a bad architecture. And unless you're a domain expert on the project and a general SoA expert, you will most likely get it wrong on the first attempt. You must know what your boundaries are before separating functionality into services. Practicing SoA may guarantee that you do SoA correctly, but it introduces significant overhead if you get those initial boundaries wrong. It's more like how Haskell will guarantee you write pure functions, but won't guarantee good functional design. SoA guarantees your services look like services, but won't guarantee good multi-service architecture. The difference is that fixing a handful of incorrect functions and fixing a handful of incorrect services is the orders of magnitude in difficulty. So yeah, still start with the call stack. At least until the boundaries become stable and clear. Dealing with SoA impurities after you've identified the boundaries is way easier than coordinating multi-service refactoring or working within a broken SoA.
- k__ 11y agoI had rather nice experiences with JavaScript. Much of it is asynchronous and these asynchronous parts are easy to refactor into services. Synchronous code wasn't that refactor friendly.