160 karma · joined January 24, 2021
So I guess it doesn't actually work for plumbing problems either.
I think the biggest benefit has been that the tests are isolated from the implementation details so we can always be sure everything is still working without having to refactor the tests themselves.
There is still a learning curve for new people because they don't know which of the multiple conventions in the code are the presently-agreed-upon ones, and that is where we could probably use some better documentation, but I think the end-to-end tests really saved us from the idea that some knowledge is lost and we might need to start over.
None of that is particularly hard, but it's a lot to build, test, and maintain. Start throwing in more account features you might take for granted elsewhere (MFA, recovery codes, re-enter current password to change your password, allow a user to sign out of all their sessions, etc etc) and you could find yourself spending all your time building your user system instead of your application features.
I would guess, for most applications, user systems are standard enough that rolling your own isn't going to be worth the possible additional customization.
To me I think the neat thing about Bitcoin is that the decentralization and lack of intrinsic value are exactly what make it (mostly) purely market driven.
Blockchain/decentralization as a technology I'm not very sold on yet.
Of course when the mania settles I have no idea if the value of digital-gold-sans-gambling would be $5 or $500,000 or $0. But I do think there is a neat idea that isn't just a pure scam buried in there.
I think once you know something might accidentally upset someone it's up to you to decide whether you want to take that chance. I try to avoid taking that chance where possible, I really don't like the idea of accidentally hurting someone.
I can also see why people are upset about their language being policed. I imagine every generation feels this way as society changes around them. I'm sure there are lots of examples of probably silly things we've policed ourselves out of saying that probably didn't amount to much, but I'm also happy we mostly don't use the pervasive casual racism of the 50's, or the pervasive casual homophobia of when I was kid.
You have to keep the guy in the factory slaving away making widgets so he can afford the Mercedes that the ad promised would make him happier so that the girl in the lab will slave away on the cure for cancer to pay for the widgets the guy in the factory made that the ad told her would make her happier.
The above sure sounds sad to me, and I can imagine another system might be better for many people in many ways, but I think it's at least an argument worth acknowledging that there is still meaningful progress to be made, and economic growth might contribute to it.
It does a good job of letting the DB do its job. Like you can define complex constraints on tables in your database and then the corresponding models will automatically detect them and have the related app-level validations. So you can keep more data integrity enforcement in the database where your transactional guarantees are but still have nice error messages in your app without duplication.
If you're looping over a collection of records it can detect if you call an association method on one of them and load the same association for all the records you're looping over in a single query, avoiding most N+1 issues.
Lots more cool stuff too. I haven't used ActiveRecord in quite a while, so I'm not sure whether it has since absorbed some of the Sequel behavior, but it's definitely worth a look.
CI runs on (almost) the exact same platform as production and we don't have to maintain any of it. When Heroku removes a package from their base image it gets removed from CI and we know if it broke anything.
The pricing model is the same as running our app. Which means if 10 people want to run 10 branches on CI at the same, and each CI run runs 32 nodes in parallel, and takes ~15 min, Heroku gives us 3200 nodes and we pay to run them for 15 minutes. No waiting, no upgrading to a different tier, etc...
I don't see many other people talking about Heroku CI, and Heroku doesn't seem to push it that much in their marketing, so either it's only really amazing for our use case or people just don't know about it yet.
For us it was a lot cheaper than other options when you consider how costly sitting around waiting for CI to start is.
Anyways that would be really hard to leave for another platform.
We've found it pretty nice to cut out a whole class of possible bugs by being able to defer it to the database level. At the application level we end up with a wrapper that sets (and guarantees unsetting) multi-tenant access to the correct tenant, and then we never have to add "tenant_id = ..." anywhere, regardless of the query. Regardless of whether we forget in some query (which we almost surely would), it cuts out quite a bit of extra code.
You can also do some cool stuff like add RLS policies for read-only multi-tenant access. Then you can query data across multiple tenants while enforcing that nothing accidentally gets written.
We ran into issues here and there but always found a way to work around them:
* Incremental backups were a pain because of needing to lock so many objects (# of schemas X # of tables per schema).
* The extra code to deal w/ migrations was kinda messy (as you mentioned).
* Globally unique IDs become the combination of the row ID + the tenant ID, etc...
For us though the real deal-breaker turned out to be that we wanted to have real foreign keys pointing to individual rows in tenant schemas from outside of the tenant schema and we couldn't. No way to fix that one since with multi-schema the "tenant" relies on DB metadata (the schema name).
We ended up migrating the whole app to RLS (which itself was a pretty interesting journey). We were afraid of performance issues since the multi-schema approach kinda gives you partitioning for free, but with the index usage on the RLS constraints we've had great performance (at least for our use case!).
After quite a bit of time working with both multi-schema & RLS I probably wouldn't go back to multi-schema unless I had a real compelling reason to do so due to the added complexity. I really liked the multi-schema approach, and I think most of the critiques of it I found were relatively easy to work around, but RLS has been a lot simpler for us.
I think we colloquially get drawn into thinking that science-as-in-physics is the same thing as science-as-in-biology is the same thing as science-as-in-economics, especially when it comes to what they all mean by "fact" and "proven". Media then takes advantage of this general misunderstanding to make "weather facts" sound like they are just as concrete as "fundamental physics facts" because it gets more attention. Then we find ourselves arguing about climate science with the same level of self-assured veracity we might argue about billiard balls on an ideal surface in a vacuum.
One nice thing for us is that we also use Heroku CI so our tests run on the same infrastructure as prod, and the pricing for Heroku CI is just based on usage with no concurrency limits so everyone can have their CI runs across all their branches happening at the same time. We tried Github Actions when Heroku CI was ahem "down" and it was slower & more expensive + the concurrency limits meant we had to wait in line to get a CI run though. Nobody else seems to use or even talk about it though, so either we have a crazy CI setup or Heroku just never marketed it.
We occasionally do the math to see if Heroku is still a good deal and the answer is always that the amount of time we estimate we're saving on devops more than pays for itself in extra time spent on app development. There's a break-even where that will no longer be the case, but as engineering & devops get more and more expensive Heroku seems like a better and better deal.
The scariest part isn't really the product itself but all the recent talk about how it's a ghost town and nobody works there anymore. It's a great product but I do hope they start innovating again.
I recently read this article about how everybody misunderstands the SRP and uses it wrong: http://www.softwareonthebrain.com/2022/01/the-misunderstood-...
Notably it was retweeted by the author of the SRP himself: https://twitter.com/unclebobmartin/status/148522452187556249...
Now neither of them went this far with it: but if we have a programming principle that nobody understands or uses right, is it really all that useful? Maybe it at least shouldn't be the first one in SOLID?
So optimistically maybe having lots of information public and easily searchable like this ultimately leads to a similar outcome. Like maybe it forces us to stop using date of birth to verify identity since it's so easy to find anyone's date of birth.
If the information is going to be out there maybe it's safer for everyone to have it than just a few people. If just a few people have it, and they use it to screw just a few other people, there's no pressure to fix it.
Or of course maybe that's wishful thinking.
Test first design makes a lot of sense, but when you’re unsure about the design using code to figure it out seems just as reasonable as any other method.
If not what’s left? Do everything waterfall?
I was actually surprised what the author was describing was somehow _not_ TDD. I thought it was pretty normal to try some things out, make some decisions, and then return to codifying those decisions in tests.
We do web app development, and 90% of our tests are browser-based integration tests that test whether the given inputs (usually forms) lead to the expected outputs (usually something printed on a web page).
I wonder if this is more natural when you're mostly writing integration tests?
I find they often end up changing or removing it.
I have a feeling that writing explanatory code comments (as in _why_ something exists) about non-conventional code might come naturally when you've really thought something through. Where vice-versa undocumented non-conventional code might be a sign that they just got something working without really thinking about how it _should_ work.
I always found the SRP too vague to be useful for actual decision making, it seems to just lead to arguments where everybody (and nobody) is correct. "Unix philosophy" sounds like it is just about as vague, or am I just really missing something that everyone else gets?
Regardless of where the fault lies that seems like a recipe for pissing of a lot of your customers, and from there it seems reasonable that the customers would be pissed at the company who sold them the product (as opposed to one of their vendors/customers).
In that light, and particularly w/ a finance app, it might seem even weirder if their angry customers _weren't_ mad at Robinhood and were willing to accept "it wasn't our fault" for any reason.
The key was we were always listening to music in our headphones.
Fundamentally the funds made an extremely risky bet and the market is (or was at one point) seemingly reasonably and expectedly betting against it with a short squeeze. The new part is the social hype driving the squeeze via an army of retail investors.
Agree some retail investors are inevitably going to be left with a net loss here, which will suck. But it was (and may still be) a reasonable play when viewing the market as a gambling platform (which the funds were doing by over-shorting).
My hope is that the people claiming to be cashing out their 401k on GME are partaking in anonymous internet hyperbole to fuel the hype and the vast majority are gambling with a few bucks they can afford to gamble with because they can't do anything else right now.
> Short interest as a percentage of float above 20% is extremely high
> A high NYSE short interest ratio means that the stock market as a whole is vulnerable to a “short-squeeze.” It could rise quickly if new economic data, political news, or other types of information are released that make investors more optimistic.
GME was shorted 140%.
No idea if 20% being risky is sage advice but it seems like you're totally right: some hedge funds took on a massive risk, the market saw the opportunity and played the other side.
I think it might be more efficient to do whatever is fastest/easiest based on what you know now & always plan on refactoring when you know more. So you end up trying to write less, simpler, code knowing you're going to tear it apart soon.
Which I think still fits with your overall point.
We write almost entirely integration tests (and lots of them) and we rarely need to maintain tests since they're only tied to the UI. Most refactors happen w/ no test changes at all. Occasionally a UI change causes a big find/replace across lots of tests.
The tests are also probably less comprehensive than a suite of finer grained tests would be. Most tests tend to cover happy path and few edge cases.
When we started there were zero tests and refactoring was too risky so the early code decisions largely had to follow the architecture that was already present (which wasn't always what we wanted). As we filled out the tests for existing behavior we could refactor more.
I think the mostly-integration-testing approach led us to a pretty good balance by only coupling the test to the UI (with its own cons of course).