1,190 karma · joined March 4, 2010
I would argue that if flipping a feature flag isn't faster than doing a rollback, your feature flags are not functional. They should be essentially instantaneous and the first thing to reach for as soon as you've identified a problem.
> Also sometimes flipping feature flags can be faster than doing a rollback, especially if multiple systems are involved.
This I totally agree with. Using feature flags well requires some discipline on the team's part to stay on top of them and remove them once they've served their purpose.
Every time ORMs get discussed, it seems to be dominated by people who are like "but my app has 5 billion concurrent users doing 2 million requests per second and if there's an extra 5ms on my requests, it will all explode!" and can't comprehend that not everyone is building the same kind of systems all the time. Great, maybe an ORM isn't appropriate for your situation.
How long ago was this? I feel like unicode has kind of been a solved problem in Python since python3 came out. In the python2 days it was, indeed, miserable.
I didn't use Fable (just Opus and Gemini) but I recently ported the `djlint` Python library to Rust, also relying heavily on LLMs (but not trying to one-shot it). `djlint` is a library to lint and reformat HTML and Django template files (and some other formats but I haven't tackled them yet as I don't really have any need). It's currently unmaintained (for a couple years at least) but was part of our CI/CD and the reformat in particular is very slow on a large codebase with thousands of templates. For our code, it took about 4 minutes to run. I generated a Rust port in a similar way, aiming for byte-for-byte output compatability. The Rust version runs on the same code in a fraction of a second; fast enough to put in a pre-commit hook. Some of that was the raw Python->Rust conversion, but a lot was some optimization work that I did afterwards. The Python version was heavily regexp-based, basically running a big slow regexp for every rule that it implements, sometimes running the regexp in a loop starting with each tag it encounters as it goes through each file. For the Rust version, I switched it to properly tokenize the files and then match rules on the AST in a single (or relatively few in some cases) pass. Honestly, there's still a lot of low hanging fruit to make it faster but it's already such a big improvement that I'm pretty happy with it. I'm sure those optimizations could've been done in Python but if I'm the one maintaining the code now, I'd much rather deal with Rust than Python with or without LLM assistance.
* Thesis/Starting Argument
* Counter-Argument (paper requirement from Naval War College)
* Rebuttal (different perspective, not your starting argument)
Sounds like someone discovering a variation on the thesis-antithesis-synthesis dialectical method from philosophy for the first time: https://en.wikipedia.org/wiki/DialecticPaine is likely well versed in the philosophy and knows exactly what she's doing. Pointing this out in case anyone wants to go deeper on this kind of approach. Much ink has been spilled over the years on different approaches, criticisms, etc.
If you're doing canary deploys to a fleet of 2000 nodes, it might take hours for the config to make it to all of them (I've seen systems where a fleet upgrade can take a week to make it all the way out). If your feature flags are configured that way, there's a long time that the state of a flag will be in that in-between state. We put feature flags in the database not config/environment so that we can turn a feature on or off more or less atomically. Ie, an admin goes into the management interface, flips a flag from off to on and then every single request that the system serves after that reflects that state. As long as you're using a database that supports transactions, you absolutely can have a clear point in time that delineates before/after that change. Rolling out a config change to a large fleet, you don't get that.
On the second point, what I'm saying is that (talk to your friendly local SRE if you don't believe me), a large percentage of production incidents in large systems are because of configuration changes, not application changes. This is because those things are significantly harder to really test than application code. Eg, if someone sets an environment variable for the production environment like `REDIS_IP=10.0.0.13` how do you know that's the correct IP address in that environment? You can add a ton of linting, you can do reviews, etc, but ultimately, it's a common vector for mistakes and it's one of the hardest areas to completely prevent human error from creating a disaster. One of the best strategies we have is to structure the system so you don't have to make manual environment/config changes that often. If you implement your feature flag system with environment variables/config, you'll be massively increasing the frequency that people are editing and changing that part of the system, which increases the chances of somebody making a typo, forgetting to close a quote, missing a trailing comma in a json file, etc.
Where I work we make production config changes maybe once a week or so and it's done by people who know the infrastructure very well, there's a bunch of linting and validation, and the change is rolled out with a canary system. In contrast, feature flags are in the database and we have a nice, very safe custom UI so folks on the Product and Support teams can manage the flags themselves, turning them on/off for different customers without having to go through an engineer; they might toggle flags a dozen times a day.