My faviourite configuration pattern for SaaS code: all the configuration for all targets, from local development setup, to unit tests, to CI throwaway deployments, to production is in a single Go package. The current environment is selected by a single environment variable.
Need something else configured beyond your code? Write Go code to emit configs for the current environment, in "gen-config some-tool && some-tool" stanza.
I have had a similar experience with a team member who was quietly unhappy about a rule. Instead of raising a discussion about the rule (like the rest of the team members did) he tried to quietly ignore it in his work, usually via requesting reviews from less stringent reviewers.
As a result, after a while I started documenting every single instance of his sneaky rule-breakage, sending every instance straight to his manager, and the person was out pretty soon.
Linux caught Kent when he tried to sneak in non-bugfixes into a RC, and berated him.
After that (not before, this is a critical distinction) Kent said "I don't want to abide by the rules, because I have my concerns".
This is very similar to the situation I have described, except that in Linux it was Linus who was skipping reviews on Kent's code trusting him not to subvert the rules, and in situation I described the team collectively was trusting each other not to subvert the rules.
You've explained everyone is unhappy with it and that you worked to get the one person who actually acted upon it fired. It's hilarious but in a pretty sad way that you're portraying this as an inevitability. It wasn't, it was just you. You had a choice, and you chose to do this. It wasn't inevitable.
I didn't make myself quite clear — the others were raising points on _other_ rules, and as a result we tuned the rules quite often, as we discovered what works better and what works worse.
PostgreSQL server is a single process that starts in under 100ms on a developer's laptop.
In the company I work for we use real PostgreSQL in unit tests — it's cheap to start one at the beginning of a suite, load the schema and go, and then shut it down and discard its file store.
I keep thinking of moving that file store to tmpfs when run on Linux, but it's nowhere near the top of the performance improvements for the test suite.
So: no more mocks or subsitute databases with their tiny inconsistencies.
For me switching the career, after spending more than 20 years in this as well... is very hard. I spent all my career outside of high-pay places like SV telling myself "I have all the time in the world, I don't need to grab most amount of money as soon as possible", so retiring is not an option.
So, switch to what? Any well-paid profession is going to be under pressure to be LLMized as much as possible.
Agree, it seems to assume that the unit of mobility is something larger, like a car. When the fundamental unit of human mobility is just that, a human, since they are inherently mobile. We would do better to describe cars as macro mobility than scooters and bikes as micro. Pipe dream, I know.
Speaking only for "micro mobility", it seems useful to distinguish allowing someone to travel within a city from between cities from between continents. Sure, it's mobility, but there are different kinds or degrees of mobility.
Drivers are difficult if you need to support lots of them. If you pick just one or a few pieces of hardware then it should be fairly straightforward. Target VMs only for example and you probably cut away 99% of the driver complexity.
For my case, I am planning to re-implement them. I like doing this.
I sure am not going to be able to re-implement everything myself though. I will concentrate on what I need, and I will consider implementing others if anyone else other than me is willing to use the OS (which would be incredible if it happened)
I clearly understand nothing of this, but it always felt confused about it. Why won't Linux aim for ABI stability? Wouldn't that be a win for everyone involved?
Cyclic logic that says you're wrong for wanting a stable kernel interface, because the kernel keeps changing so the solution is to just get your code merged into mainline. As a tautology, it's true, but it's also a cover for "because we don't want to".
See Windows or android GKI for existence proof that it can be done if so motivated.
From what I understood, I think the big difference here is the human factor: Windows and Android are maintained by employees, who have no choice but to work on things even if they don't like doing it. Linux on the other hand is a collective effort of people doing what they want to do on their free time.
They come from employees of various companies, not employees of some company that owns Linux itself. All those various companies have different goals, and are only contributing because doing so is in their economic interest. Having a stable ABI would require a lot more work, and these companies have zero incentive to invest in this effort: it doesn't help their profitability, it just makes things easier for others outside their companies. Arguably, it also makes the kernel code a lot more complicated and bug-prone.
It makes sense for MS, for example, to want a stable ABI to make things easier for 3rd-party devs so they'll target that platform, and for MS to shoulder the effort of maintaining that ABI cumbersomeness. It doesn't really makes sense for Linux. You could argue that this hampers adoption of Linux as an alternative to Windows on desktop machines, but even if that's true, no one involved really has an economic incentive to change this. In the places where Linux is dominant (Android + servers + embedded), a stable ABI isn't really helpful or needed.
TL;DR: maintaining a stable driver ABI is more work because you have to deal with backwards compatibility, and it mainly benefits vendors that don't make their drivers open source.
So the Linux devs are really against it both from a lack of resources point of view, and from an ideological "we hate closed source" point of view.
Unfortunately, most vendors with closed source drivers don't give a shit about ideology and simply provide binaries for very specific Linux releases. That means users end up getting screwed because they are stuck on those old Linux versions and can't upgrade.
The Linux devs have this strange idea that vendors will see this situation as bad and decide that the best option is to open source their code, but that never happens. Even Google couldn't get them to do that. This is one of the main reasons that Android OS updates are not easy and universal.
> My understanding is that the userspace interface is extremely stable.
Assuming you compile a static binary that doesn't even rely on libc, then yes, something compiled 20 years ago will still run.
But in the real world you have to recompile your software constantly due to breakage in dependencies (including glibc). And a binary won't work cross-distros without adding efforts despite running the same kernel (sure, that part isn't the kernel's fault).
It's often memed that the most stable interface on Linux is win32 (via wine), and that meme isn't entirely off-base.
I thought that unless you're relying on buggy behaviour, or other implementation-specific details which are explicitly and prominently documented as unsupported and/or subject to change[0], any binary compiled for Linux libc6/glibc2 (released in Jan '97, available in e.g. Debian "Hamm" in July '98) should still run with the most recent glibc today.[1] Is that not right?
[0] e.g. if your app has a use-after-free bug which happened to work 20 years ago, it may not work any more. Although SimCity famously had a bug like this on Windows, and Microsoft put in a SimCity-specific "shim" to ensure it would continue working when they changed Windows' allocator, if your app is not as popular as SimCity was then it probably won't be as lucky, even on actual Windows.
[1] for the same architecture, obviously. Your i386 app won't run with an s390x or amd64 glibc.
Aren't most drivers kernel modules? In theory, the goal to aim for is that Maestro is able to compatibly load C Linux kernel modules. Then, whether or not the driver module is written in C or Rust is orthogonal to which kernel is used.
(Just bs'ing here, haven't written drivers in over a decade. What other complexity am I missing?)
My faviourite configuration pattern for SaaS code: all the configuration for all targets, from local development setup, to unit tests, to CI throwaway deployments, to production is in a single Go package. The current environment is selected by a single environment variable.
Need something else configured beyond your code? Write Go code to emit configs for the current environment, in "gen-config some-tool && some-tool" stanza.