A routine gem update ended up creating $73k worth of subscriptions
291–300 of 336 posts
Re: A routine gem update ended up creating $73k worth of subscriptions
#292Earlier quoted context omitted.
Somewhat related to your points of music... There's an episode of "This is Pop!" on Netflix that explores why the Swedes write so many pop hits. One of the arguments presented is that they speak English well as a second/third language so they're less focused on the lyrics making sense and being grammatically correct, and are free to make lyrics that sound like they work but are non-sensical on reflection. It's just t…
The song “I want it that way” comes to mind, the song topped many charts including in the US, and the lyrics are very strange upon reflection. What does “I never wanna hear you say. I want it that way.” mean exactly? Apparently the Swedish songwriter barely spoke any English at all at the time.
Even more recently, Shake it Off by Taylor Swift.
Somewhat along the same lines, I was watching the Get Back documentary on the Beatles and the number of songs they write by effectively scatting and then filling in the words that were their big hits is amazing.
Again they're writing to fit the tune, then in filling the words based on a general theme. It's very different than the songs they write where you can tell someone's sat down and written the words first.
Re: A routine gem update ended up creating $73k worth of subscriptions
#293Earlier quoted context omitted.
I think you may have slightly misunderstood the issue—the problem isn't that the method was returning too many accounts, the problem was that the method was returning an account unrelated to the one whose subscription had expired . Therefore, subsequent calls by the same expired user would renew for more and more random accounts—but only one random account per call.
Yeah I didn't look into it.. But reading further, it still would've prevented this bug. If you expect 1 or 0 results, just make sure it does. The query here returned where id = xxx or renew_locked_at >= xxx or renew_locked_at is null. That will return more than 1 result. If find_one actually did what the name says it does, find 1. Not 0, not 2, not 475. This issue would've never existed. Both mongoid and activerecord…
Both raise an exception unless a single record is found.
Of course this would not make a difference when working with mongoid... I also like the fail fast approach.
https://blog.saeloun.com/2021/03/16/rails-adds-sole-and-find...
Re: A routine gem update ended up creating $73k worth of subscriptions
#294Earlier quoted context omitted.
Certainly it has something to do with the ecosystem, if the most popular MongoDB driver in the ecosystem is making breaking changes in minor versions. That said, strong types can be a godsend for catching accidental breaks, even if it wouldn’t necessarily have helped here. A strongly typed language that has a more disciplined ecosystem is less likely to run into these kinds of issues. It’s one of the tradeoffs you pi…
This is exactly the case where nothing about types, language or opinions about the Ruby community has to do with the problem at hand. This would not be caught by compiling, strong types or anything else - this is a change in behavior which has been arbitrarily done by the maintainers of the dependency. > Certainly it has something to do with the ecosystem, if the most popular MongoDB driver in the ecosystem is making…
> How should this be handled? Should a "good" ecosystem vet every single change in every single library that gets updated? Or should there be no libraries and only stdlib instead (wait, I think I know a compiled language which did just that for quite a few years, let me think which one that was again...)
This isn’t really about Ruby vs all compiled languages, I mean, Brainfuck is a compiled language and that doesn’t mean I was endorsing Brainfuck to replace Ruby. However I would certainly endorse Go to replace Ruby. Rust too, although using Rust to do web development stuff feels like using a nuclear warhead to open a door.
Anyway, the reason why types is relevant to this discussion is because types are contracts that are statically enforced and the break that occurred happened due to a contract change. This change illustrates that even if you do have types it doesn’t guarantee you won’t have breaking contract changes. However, eliminating entire classes of accidental or intentional contract breaks is an obvious win/win. If it was as complex and obtuse as C++, nobody would bother. But C++ isn’t the only game in town anymore for fast compiled strongly typed languages.
Re: A routine gem update ended up creating $73k worth of subscriptions
#295Earlier quoted context omitted.
I'm guessing the sentence they wrote is just a consequence of English not being the author's primary language. I frequently see ESL speakers get adjective and adverb positions wrong in ways that unintentially change the meaning. Even skilled English speakers make mistakes here because English is both very permissive about word order, but also tends to give different shades of meaning to each other. "Only" is a pernic…
It’s kind of like the saying, “all that glitters is not gold”. Gold doesn’t glitter? That makes no sense. English syntax is not mathematical logic. The song, “I Can’t Get No Satisfaction” is not a song about someone who is forced to receive satisfaction.
Open any book or paper on semantics (the linguistics kind, not the philosophy or the early-20th-century pseudoscience kind) and you might be surprised :) It’s just that the logic is not that straightforward to get out, and of course there’s semantics (the literal meaning, where “Can you pass the salt?” is a question about ability) and then there’s pragmatics (the thing one is actually trying to communicate, where “Can you pass the salt?” is a request with certain degrees of respect and formality attached to it).
> “I Can’t Get No Satisfaction”
This is probably not a very good example as it’s just (AFAIU) not strictly “standard English” in that it exhibits negative concord absent from the standard grammar (for dramatic effect, although “We Don’t Need No Education” is probably a better case). That is to say, this is a phrase in a language (which is very similar to standard English but not quite the same) where the grammar requires dummy negations on complements of negative verbs—a purely syntactic thing that doesn’t even reach the layer of semantics / logic.
But then many other varieties of English do that (I remember reading somewhere that the dialect that gave rise to the current standard is actually somewhat unusual among other dialects in that respect), so does my native Russian (and other Slavic languages, and some but not all Romance ones), and Japanese actually requires you to negate the adjective when using the adverb meaning “hardly, not very”[1] while at the same time using some double negations as polite affirmations[2].
Re: A routine gem update ended up creating $73k worth of subscriptions
#296Earlier quoted context omitted.
Stripe charges the same for reminds as regular charges, so approximately 3%.
Actually, refunds are free, but Stripe keeps the original fee for payment processing and covers it out of that. So you need to pay the transaction fee for the original purchase to make the customer whole. See https://support.stripe.com/questions/understanding-fees-for-... . In this case, since we know from the article that there are 474 charges, and a total of $73k processed, 474 * $0.30 + $73k * 0.029 comes out to $…
Re: A routine gem update ended up creating $73k worth of subscriptions
#297Earlier quoted context omitted.
You're right that the language isn't to blame as such. But if a change like this doesn't cause some kind of uproar in the Ruby community, then the community has a problem.
It won’t cause a uproar because Ruby/Rails changes APIs on minor versions all the time. Breaking changes are pushed at a yearly rate and everyone is just expected to cope with them.
Re: A routine gem update ended up creating $73k worth of subscriptions
#298Earlier quoted context omitted.
Yeah I didn't look into it.. But reading further, it still would've prevented this bug. If you expect 1 or 0 results, just make sure it does. The query here returned where id = xxx or renew_locked_at >= xxx or renew_locked_at is null. That will return more than 1 result. If find_one actually did what the name says it does, find 1. Not 0, not 2, not 475. This issue would've never existed. Both mongoid and activerecord…
Rails 7 has finally added this to active record: sole and find_sole_by Both raise an exception unless a single record is found. Of course this would not make a difference when working with mongoid... I also like the fail fast approach. https://blog.saeloun.com/2021/03/16/rails-adds-sole-and-find...
Re: A routine gem update ended up creating $73k worth of subscriptions
#299Earlier quoted context omitted.
We're just trading anecdotes at this point but I can't say I've encountered the same problems over the past decade of working with it. That's generally because of limiting dependencies, but also because it's a good idea to peek at the changelog or release notes when bumping the minor or major version. TFA doesn't mention or acknowledge this aspect of the issue, but it did surprise me that they considered a version bu…
It took you 5 minutes to find the info because you knew what you were looking for. Expecting programmers to audit all of their code before a minor update is ridiculous.
Re: A routine gem update ended up creating $73k worth of subscriptions
#300Earlier quoted context omitted.
It took you 5 minutes to find the info because you knew what you were looking for. Expecting programmers to audit all of their code before a minor update is ridiculous.
Seriously? It's eminently reasonable to expect you to know the code you're deploying. Perhaps you're a JS developer. I agree it's incredibly difficult to keep up with the churn there, but in my Elixir deps, the updates tend to be less frequent and more reviewable. Some deps you can trust the owner and just carefully review the change log. Even that would have caught this issue, though I'm not sure I'd count this gem…
Maybe you are a very careful developer, but the vast majority out there is not.
Shipping an udate that will corrupt data if you don't read the changelog is very very dangerous.
I see why they did it. Having a method with the same name as in Active Record but with different behavior is also dangerous.
But they really could have handled this better.