https://digitstodollars.com/2022/06/15/what-has-broadcom-bec...
122 karma · joined January 21, 2022
https://digitstodollars.com/2022/06/15/what-has-broadcom-bec...
Sounds like you might be interested in https://antithesis.com/ (no affiliation).
As a matter of fact, EnterpriseDB (the largest contributor to Postgres) has a paid multi master offering, so there's anti incentives in place to improve its HA story...
Easier said than done, of course!
People without aphantasia literally count sheep to go to sleep.
1. I think that it is preferable to handle the error where it happened instead of at the top of the stack. For a backend service, there's really only three things you want to do with an error: log it, maybe bump some metrics, and return an error code and ID to the client. You have a lot more information available (including a stack trace if desired) if you handle it at this point.
2. By wrapping the error up the call stack, you're building an ad hoc stack trace. Performance wise, this is (probably, haven't measured) a lot better than an actual stack trace, but as you said yourself, the top concern is debug-ability and developer velocity.
3. Wrapping an error doesn't provide just a stack though, you can add values to the error! Except...what does that really buy you vs. just adding the values to your structured logging system going down the stack vs. doing it on the way back up in an ad-hoc way? Those wrapped error values are a lot more difficult to work with in Grafana vs. searching based on fields.
4. If I have a stack trace, structured log fields, and a correlation ID, I personally don't get any value out of messages like ("could not open file), as I can just use the stack trace to go look at exactly what the line of code is doing. You could argue that with good enough wrapping, looking at the code wouldn't even be necessary, but I think that's pretty rare in practice. It also seems like a lot of extra work to spend a minute loading up the code in an IDE.
5. As mentioned in 1), what the client gets is just an error code and trace ID anyways. In fact, we actively don't want the wrapped context to be sent back to the client since it can be a security concern. If that's the case, we need to remove it and log it anyways. Why not just log the information in the first place?
Anyways, curious to hear your thoughts. I used to advocate for wrapping errors, FWIW.
From a quick look at the code, this looks the magic line: https://github.com/phoenixframework/flame/blob/main/lib/flam...
Can you expand on how you perceive traditional RDMSs to be different for this case?
What did the API of the meeting service look like specifically?
1. A misunderstanding of the business rules. In the flight example, you thought that were flights were cancellable, but actually the airline only offers nonrefundable seats.
2. System type errors, e.g. network outages.
If you get a type 1 failure, that's an error that gets ingested in your error monitoring service, and is a bug that needs to be fixed. If you get a type 2 failure, idempotent cancellation (which is necessary for this work) will eventually get you to your desired state. Either way, you shouldn't need to model deeper into the state graph.
1. You book a flight. You successfully reserve a seat.
2. You book a car. You successfully reserve a sedan.
3. You try to book a hotel room. The room that you wanted was booked while you were booking your flight, and there aren't any more available.
You obviously don't want the car or flight anymore, and you want to cancel them without a human having to manually fix it.
You don't need to explicitly interact with an event queue because it's a higher level abstraction that sits on a queue. In fact, that’s the big value add.
ACID doesn't help you once you're trying to coordinate actions across systems, like the example in the article.
Any transaction which is run at a transaction isolation level other than SERIALIZABLE will not be affected by SSI. If you want to enforce business rules through SSI, all transactions should be run at the SERIALIZABLE transaction isolation level, and that should probably be set as the default.
Given that running everything at SERIALIZABLE probably isn’t practical for you, I think it’s more clear code wise to use explicit locks. That way, you can grep for what queries are related synchronization wise, vs. SERIALIZABLE being implicit.