Live data from Hacker News

Anti-patterns in event-driven architecture

codeopinion.com

141–150 of 171 posts

Re: Anti-patterns in event-driven architecture

#141
post #59

Can someone share some long term event driven success stories? Almost everything you see online is written by consultants or brand new, greenfield implementations, curious how long these systems last.

The project I'm working on is about 13 years old (ruby on rails) with over 260 engineers and the product has a very robust event driven system that is at the core of a lot of important features.

Out of curiosity, what is the system? Is this based on Rails Event Store, or something else (custom?)?

Re: Anti-patterns in event-driven architecture

#142
post #37

What are people’s thoughts on using event driven architecture in games? Specifically multiplayer games, and massively multiplayer games (MMOrpgs). Another comment mentions it was helpful, how specifically, were there any tradeoffs, do certain types of games work better?

I have not worked on an MMO before, but recently I had the chance to try out my own custom event system on a small multiplayer game (Unity, PUN2). I had most issues with differentiating which events came from which client. Additionally, I had lots of issues differentiating which events were issued locally. In the end, the code ended up being quite messy. If I were to redo the game, I'd use direct method calls where possible with regular callbacks.

Generally, I found that when using event systems you have to be really careful not to over-use it, even small/single player games. Its super hard to debug when everything is an event - if you go this route, you essentially end up in a situation where everything is "global" and can be reached from anywhere (might as well just go full singleton mode at that point). Additionally, I found it difficult having to deal with event handlers which raise other events, or worse, async events, as then it becomes really hard to ensure the correct order of invocations.

If you plan to use an event system, my advice would be (in Unity): - Reference and raise events only on root Game Object scripts (e.g., have a root "Actor" script which subscribes/publishes events and communicates with its children via properties/C# events) - Never subscribe or publish events in regular "child" components - Use DI/service locator to fetch systems/global things and call them directly when possible from your "Actors"

Re: Anti-patterns in event-driven architecture

#143

Not specifically about event-driven, but the most damaging anti-pattern I would say is microservices. In pretty much all projects I worked with in recent years, people chop up the functionality into small separate services and have the events be serialised, sent over the network and deserialised on the other side. This typically causes enormous waste of efficiency and consequently causes applications to be much more…

Also, the single most nonsensical reason that people give for doing microservices is that "it allows you to scale parts of the application separately". Why the fuck do you need to do that? Do you scale every API endpoint separately based on the load that it gets? No, of course not. You scale until the hot parts have manageable load and the cold parts will just tag along at no cost. The only time this argument makes s…

> Also, the single most nonsensical reason that people give for doing microservices is that "it allows you to scale parts of the application separately". Why the fuck do you need to do that? Do you scale every API endpoint separately based on the load that it gets? No, of course not. You scale until the hot parts have manageable load and the cold parts will just tag along at no cost. The only time this argument makes sense is if one part is a stateless application and the other part is a database or cache cluster.

I think it really matters what sort of application you are building. I do exactly this with my search engine.

If it was a monolith it would take about 10 minutes to cold-start, and it would consume far too much RAM to run a hot stand-by. This makes deploying changes pretty rough.

So the index is partitioned into partitions, each with about a minute start time. Thus, to be able to upgrade the application without long outages, I upgrade one index partition at a time. With 9 partitions, that's a rolling 10%-ish service outage.

The rest of the system is another couple of services that can also restart independently, these have a memory footprint less than 100MB, and have hot standbys.

This wouldn't make much sense for a CRUD app, but in my case I'm loading a ~100GB state into RAM.

Re: Anti-patterns in event-driven architecture

#144
post #85

Earlier quoted context omitted.

Almost every modern software system. Anything running over the Web is event driven.

99.99% of the data we consume on the Web comes out of databases [call it Transactional-SQL-xxx or ColumnBased-yyy or Elastic-SaaS-zzz].

Well, yes. Databases are event driven themselves.

As is any web application, because the web (at least without sockets) is constrained into communicating events only.

Also, most local GUI applications, because people just like events better for it.

Re: Anti-patterns in event-driven architecture

#145

Not specifically about event-driven, but the most damaging anti-pattern I would say is microservices. In pretty much all projects I worked with in recent years, people chop up the functionality into small separate services and have the events be serialised, sent over the network and deserialised on the other side. This typically causes enormous waste of efficiency and consequently causes applications to be much more…

Also, the single most nonsensical reason that people give for doing microservices is that "it allows you to scale parts of the application separately". Why the fuck do you need to do that? Do you scale every API endpoint separately based on the load that it gets? No, of course not. You scale until the hot parts have manageable load and the cold parts will just tag along at no cost. The only time this argument makes s…

> Why the fuck do you need to do that?

Because deploying the whole monolith takes a long time. There are ways to mitigate this, but in $currentjob we have a LARGE part of the monolith that is implemented as a library; so whenever we make changes to it, we have to deploy the entire thing.

If it were a service (which we are moving to), it would be able to be deployed independently, and much, much quicker.

There are other solutions to the problem, but "µs are bad, herr derr" is just trope at this point. Like anything, they're a tool, and can be used well or badly.

Re: Anti-patterns in event-driven architecture

#146

Not specifically about event-driven, but the most damaging anti-pattern I would say is microservices. In pretty much all projects I worked with in recent years, people chop up the functionality into small separate services and have the events be serialised, sent over the network and deserialised on the other side. This typically causes enormous waste of efficiency and consequently causes applications to be much more…

Also - you give up type safety and refactoring. LoL

Re: Anti-patterns in event-driven architecture

#147

Earlier quoted context omitted.

Oh, it is even worse. The MAIN reason for microservices was that you could have multiple teams work on their services independently from each other. Because coordinating work of multiple teams on a single huge monolithic application is a very complex problem and has a lot of overhead. But, in many companies the development of microservices/agile teams is actually synchronised between multiple teams. They would typica…

I've worked with thousands of other employees on a single monolithic codebase, which was delivered continuously. There was no complex overhead. The process went something like this: 1. write code 2. get code review from my team (and/or the team whose code I was touching) 3. address feedback 4. on sign-off, merge and release code to production 5. monitor logs/alerts for increase in errors In reality, even with thousan…

Regarding monoliths...when there's an issue, now everyone who made a PR is subject to forensics to try to identify cause. I rather make a separate app that is infrequently changed, resulting in less faults and shorter investigations. Being on the hook to try to figure out when someone breaks "related" to my team's code, is also a waste of developer time. There is a middle ground for optimizing developer time, but putting everything in the same app is absurd, regardless of how much money it makes.

Re: Anti-patterns in event-driven architecture

#148

Earlier quoted context omitted.

I've worked with thousands of other employees on a single monolithic codebase, which was delivered continuously. There was no complex overhead. The process went something like this: 1. write code 2. get code review from my team (and/or the team whose code I was touching) 3. address feedback 4. on sign-off, merge and release code to production 5. monitor logs/alerts for increase in errors In reality, even with thousan…

Regarding monoliths...when there's an issue, now everyone who made a PR is subject to forensics to try to identify cause. I rather make a separate app that is infrequently changed, resulting in less faults and shorter investigations. Being on the hook to try to figure out when someone breaks "related" to my team's code, is also a waste of developer time. There is a middle ground for optimizing developer time, but put…

I'm not sure how you think microservices gets around that (it doesn't!).

We didn't play a blame game though... your team was responsible for your slice of the world and that was it. Anyone could open a PR to your code and you could open a PR to anyone else's code. It was a pretty rare event unless you were working pretty deep in the stack (aka, merging framework upgrades from open source) or needing new API's in someone else's stuff.

Re: Anti-patterns in event-driven architecture

#149

Not specifically about event-driven, but the most damaging anti-pattern I would say is microservices. In pretty much all projects I worked with in recent years, people chop up the functionality into small separate services and have the events be serialised, sent over the network and deserialised on the other side. This typically causes enormous waste of efficiency and consequently causes applications to be much more…

Also - you give up type safety and refactoring. LoL

Well, technically, you can construct the microservices preserving type safety. You can have an interface with two implementations

- on the service provider, the implementation provides the actual functionality,

- on the client, the implementation of the interface is just a stub connecting to the actual service provider.

Thus you can sort of provide separation of services as an implementation detail.

However in practice very few projects elect to do this.

Re: Anti-patterns in event-driven architecture

#150

Earlier quoted context omitted.

Also, the single most nonsensical reason that people give for doing microservices is that "it allows you to scale parts of the application separately". Why the fuck do you need to do that? Do you scale every API endpoint separately based on the load that it gets? No, of course not. You scale until the hot parts have manageable load and the cold parts will just tag along at no cost. The only time this argument makes s…

> Why the fuck do you need to do that? Because deploying the whole monolith takes a long time. There are ways to mitigate this, but in $currentjob we have a LARGE part of the monolith that is implemented as a library; so whenever we make changes to it, we have to deploy the entire thing. If it were a service (which we are moving to), it would be able to be deployed independently, and much, much quicker. There are oth…

Yes. There are costs to having monoliths. There are also costs to having microservices.

My hypothesis is that in most projects, the problems with monoliths are smaller, better understood and easier to address than the problems with microservices.

There are truly valid cases for microservices. The reality is, however, that most projects are not large enough to qualify to benefit from microservices. They are only large projects because they made a bunch of stupid performance and efficiency mistakes and now they need all this hardware to be able to provide services.

As to your statement that deploying monoliths takes time... that's not really that big of a problem. See, most projects can be engineered to build and deploy quickly. It takes truly large amount of code to make that real challenge.

And you still can use devops tools and best practices to manage monolithic applicaitons and deploy them quickly. The only thing that gets large is the compilation process itself and the size of the binary that is being transferred.

But in my experience it is not out of ordinary for a small microservice functionality that has just couple lines of code to produce image that take gigabytes in space and takes minutes to compile and deliver, so I think the argument is pretty moot.

Post reply on HN