Idempotence now prevents pain later
71–80 of 133 posts
Re: Idempotence now prevents pain later
#72This is good but not enough. You also need to be sure that you can’t charge twice if the job runs twice. When you do that same query twice, you will get the same list of users. This could be done by exploiting database consistency rules, like using strongly isolated transactions. One simple more general approach is to use an idempotence token. You could, say, have a table with a uniqueness constraint, and generate ID…
That's handled by the extra condition in step 1 of the altered rules:
> which haven't been charged the fee this month.
Re: Idempotence now prevents pain later
#73Re: Idempotence now prevents pain later
#74This is good but not enough. You also need to be sure that you can’t charge twice if the job runs twice. When you do that same query twice, you will get the same list of users. This could be done by exploiting database consistency rules, like using strongly isolated transactions. One simple more general approach is to use an idempotence token. You could, say, have a table with a uniqueness constraint, and generate ID…
Re: Idempotence now prevents pain later
#75Great idea if you control all the inputs (I'd also suggest passing in a time instead of relying on time.Now or whatever your language gives you). Sometimes you don't and it's very hard to do.
Re: Idempotence now prevents pain later
#76Great article. This is really about a mental shift. When given a problem like "dormant customers should be charged", it's natural to model the problem as verbs: "find the dormant customers and charge them". However, that description relies on implicit state: it assumes a world where all dormant customers have not been charged. As we all know, relying on hidden implicit state is the source of all evil. When you descri…
> think of your problem purely in terms of the world you want to end up in as a result Great framing! Isn't this the difference between imperative and declarative statements/code/systems?
Re: Idempotence now prevents pain later
#77Earlier quoted context omitted.
This could still lead to a double-charge, though. If some rogue deploy script creates fifty of the cron job, and weirder things happen every day, one of those could be checking the stale state during the transaction of another one. A classic data race. Eliminating this problem is left as an exercise for the interested reader...
The way to fix that is to remove state altogether. 1. Balance is not a simple variable, but the sum of all credits and debits to an account 2. A fee is a charge record in your database 3. This fee has a database constraint that you can have only one record per month Now you can run the script that charges dormant fees as often as you want.
Practically speaking, this narrows your "transaction window" significantly - instead of:
1. Begin transaction
2. Check to see if work has already been done
3. Do work
4. Persist work
5. Commit
With a potentially long transaction spanning from 1-5, you do this: 1. Do work
2. Persist work to key / table with uniqueness constraint
3. On conflict, do nothing (looks like you already did the work before)
Of course if "Do work" is very expensive, you can bring back in "Check to see if work has already been done" as an optimization, but for many simple CRUD examples, it's actually /cheaper/ to learn that the work has already been done via the conflict check failing than via an explicit pre-flight check.Re: Idempotence now prevents pain later
#78Great article. This is really about a mental shift. When given a problem like "dormant customers should be charged", it's natural to model the problem as verbs: "find the dormant customers and charge them". However, that description relies on implicit state: it assumes a world where all dormant customers have not been charged. As we all know, relying on hidden implicit state is the source of all evil. When you descri…
Re: Idempotence now prevents pain later
#79Googler opinions are my own. I work on payments stuff. Payments at Google defined some specs for payment companies to build to, which allows easy onboarding as a form of payment on google's platform. We have a page talking about idempotency and expected behavior. https://developers.google.com/standard-payments/reference/id... I don't think it's that different from other payment companies, like adyen or worldpay, but…
Re: Idempotence now prevents pain later
#80Also, in web front end programming, there are lots of cases where X needs to cause Y to happen, but Z also needs to cause Y to happen. It's much much simpler if Y is idempotent, rather than X checking if Z has already happened etc.