Totally agree. I wish UPSERT had been invented earlier, or was a more canonical part of SQL than INSERT and UPDATE for this reason. Also, 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.
I'm going to make an absolutist statement for which I will probably be corrected shortly. For any given table, interactions should either be done entirely with INSERT or be done entirely with UPSERT. The two should never mix on a single table, and UPDATE should never be used. My reasoning is that if a table represents the current state of the world, then any state changes should be made with UPSERT in order to bring…
Idempotence now prevents pain later
111–120 of 133 posts
Re: Idempotence now prevents pain later
#112I have worked on lots of software that involves event-driven actions, and apply this concept throughout. "Need to send a notification email when x condition becomes true". Naive way: during processing, check the condition and call the SendEmail() function. Idempotent way: Run a query that finds all x conditions, join to a list of notifications based on email+id+time, and only if there's no entry, send the notificatio…
One of the experiences I had was applying it to provisioning with idempotent shell scripts, combined with a trivial tool like https://github.com/lloeki/apply
Creating a VM in DO would add the basic SSH keys, then just run the thing against the new IP. Boom, VM ready. Want to make existing VMs config up to date? Apply. Boom.
The whole thing ridiculously scaled up in a totally unexpected way, saving hundreds of hours of headaches and mistakes.
Why not ansible/puppet? Check out the rationale in the readme.
Re: Idempotence now prevents pain later
#113> 2. Charge each of these accounts a fee.
There's still a race condition between 1. and 2. if you don't atomically check the account hasn't been charged yet as you're charging it.
With long running processes like these it's also pretty much guaranteed to happen if you accidentally run two instances of this process at the same time.
Re: Idempotence now prevents pain later
#114Impotence now also prevents pain later: having kids is such a pain in the arse.
Re: Idempotence now prevents pain later
#115Earlier quoted context omitted.
I'm going to make an absolutist statement for which I will probably be corrected shortly. For any given table, interactions should either be done entirely with INSERT or be done entirely with UPSERT. The two should never mix on a single table, and UPDATE should never be used. My reasoning is that if a table represents the current state of the world, then any state changes should be made with UPSERT in order to bring…
I'm probably being stupid here but the majority of updates only involve a limited number of columns. How would you translate a statement like 'UPDATE customers SET surname='Smith' WHERE customer_id = 1234' into an UPSERT?
One impact of this is that is forces the changes to be atomic. If an object-oriented interface updates a database whenever properties are changed, then it results in many single-column changes. In the example below, if there is a network failure between the two commands, then changing the name from "Jane Doe" to "John Smith" could result in an unintended intermediate state of "John Doe".
customer_obj.set_forename("John")
customer_obj.set_surname("Smith")
(Again, I am by no means an expert, and in part posted this so that I can be corrected if/where I am wrong.)Re: Idempotence now prevents pain later
#116> We need to charge dormant customers a monthly fee so that we don't have to keep their money on our accounting books forever.
That's absolutely and objectively not the reason this happens. Keeping their money "on [your] books" has zero cost associated with it outside of the escheatment[0] process, which can be completely automated. I worked at a company that had to do a decent amount of escheatment for almost every US state, Canada, and Mexico, and for a total company size of under ten people the entire organization probably spent 45 minutes working on it in any given month. It's a trivial amount of time.
This happens to that the company can turn it's customers' money into its money. I don't know enough about to escheatment process to know for sure but I'd imagine regular debits like this would also get around the need to return the money to the estate after a given period of time. So someone puts $500 in their account, gets hit by a bus the next day, and the company gets to take a little bit every month/quarter/year until it's all theirs.
It's a pretty scummy thing to do and I'm surprised the author just takes it at face value that they "have to" do it.
[0] https://en.wikipedia.org/wiki/Escheat#Transfer_agents_and_es...
Re: Idempotence now prevents pain later
#117Re: Idempotence now prevents pain later
#118I have worked on lots of software that involves event-driven actions, and apply this concept throughout. "Need to send a notification email when x condition becomes true". Naive way: during processing, check the condition and call the SendEmail() function. Idempotent way: Run a query that finds all x conditions, join to a list of notifications based on email+id+time, and only if there's no entry, send the notificatio…
This was common when I was writing puppet. It was easy to have your entire puppet run take minutes - and want to run every few minutes - while consuming a LOT of cpu time including on a centralised server and not just the end host.
There are of course ways and strategies to this and not every situational falls afoul of it. But it is something you very much need to be aware of.
I otherwise whole heartedly endorse this.
Re: Idempotence now prevents pain later
#119Earlier quoted context omitted.
Thank you, this will blow my mind. I will take this path. Real time systems is the field which is where I want to be.
To add to this part: "My main epiphany was that realtime applications do not exist. Rather they cannot exist." Most of us think our applications are realtime (never mind the OS schduling cpu time for your code, so inherently not realtime) but this is only because it behaves as expected, while there is not too much load nor too much data. The moment you start having significant computational load or start having too m…
By the time you perceive anything, and even more so by the time you react to it, it's already in the past.
There is no "now", it's all an approximation.