🔧 Programmierung 🕛 vor 11 Monaten 5 Min Lesezeit
0

Sentient Config is a Code Smell

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Stop me when this starts to feel familiar:




  1. You build a really cool app that does a thing.

  2. You have another use-case for the app, but maybe for a slightly different setup. So you add some configuration variables, maybe via environment variables or CLI args.

  3. This works well, and you start to dream bigger. More use cases spring to mind that are effectively the same app, but with more tweaks. More configuration variables are needed. You evolve to config files.

  4. Config files allow you to go bigger. More workloads, all running on the same base code! But suddenly, your base code doesn't quite do the thing you need it to. Suddenly your config values, no matter how nested and complex, can't get you to where you need to be. That's when the whispers start.



"These config files let me inject functionality into code. Code is functionality. In fact, why couldn't I just inject a little code from a config file. Then I wouldn't even need to make a pull request."



It is at this precise moment that you need to SNAP OUT OF IT. Much like Frodo with the One Ring, I'm being your Samwise Gamgee right now. Stop. It.



Look at where you are. You were just giddy about being able to "inject" code into your app without "having" to go through the "pain" of making a pull request. Do you see what the config file whispers have done to you?






Beware the Sentient Config



I hope that you've only experienced the brief wondering if hardcoding Python in YAML strings is really that bad. I hope you haven't gone down the road that some go: the road to mini-programming-languages-as-config.



If your config starts to become semi-executable, or--heaven forbid--Turing-complete, you may want to take another look at your architecture

and see if there aren't some quality-of-life improvements to be made. Here's an example similar to some sentient config in a legacy app I worked on:




CODE
{
"title": [
["regex", "(\w+\n===================)"],
["split"],
["strip"],
["replace", "&", "&"]
]
}






(sobs in JSON)



Because, while the above isn't terrible, 1. it's possibly not under source

control, and 2. it would be 5% more readable in actual code, and 3. it's an active gateway even more Turing. How long does this go on before you start to really crave an if expression, or--OK, maybe not that, but perhaps just a few boolean ands and ors? Or, perhaps, map, reduce, filter, and a first?




If a situation feels like it would be improved by allowing some custom code, the right solution is probably some custom code, done properly, and not more config.







Consider a Different Mindset



At times like these, it's important to ask ourselves: "What are we doing here? What's our goal?"



At least in our case, one issue we had been seeing is that our "custom code modules" were all bundled together in a package which the main app installed as a dependency, so anytime we wanted to tweak one specific custom module, we'd have to make that PR and deploy that new version, bump it in the main app, and bump that app's deployments, only to find out that we had a small bug and another round of PR's followed. This was understandably frustrating. So the workaround was more sentient config that we could configure live, on the fly, with fewer hoops to jump through.



But, as we took a step back to reflect (right around the time we started

drafting proposals for if statement syntax), we realized that we could do with an inversion:



Our "main app" became our "base library." Our "custom modules" became individual "main" modules that extended, expanded, and customized our new base library. And we gained the following benefits:




  • We dropped one or two bump-and-redeploy cycles per code change.

  • We were able to really hone and polish our new "base library" because it
    wasn't yet overcomplicated by so many config variables.

  • Our base library stopped changing so frequetly to accomodate new edge cases.

  • The previous two points allowed us to dramatically and confidently increase
    our test coverage of the base library, knowing we wouldn't have to rewrite the
    tests in a month.

  • Debugging, fixes, and new apps/module development saw huge speedups, because,
    now our engineers weren't trying to figure out where the bug was in our awful,
    lightly documented, poorly tooled quasi-Lisp, they could quickly debug in
    Python code with Python tools like the grown, strong, independent software
    engineers we hired them to be.

  • Onboarding got faster because new hires already knew Python and didn't have to
    learn a new "language" (with those quotes doing lots of deeply malice-filled
    work here).






Inherit with Caution



I want you to hear me very clearly here. I am not advocating for you to go

forth and design up 52 layers of BaseMiddleGenericAbstractMixin classes to

override. Some inheritance may make sense. Some composition via components

probably would go a long way. But, just because you're planning on "extending

the base functionality" in your individual apps doesn't mean that it has to be

done via way too much inheritance.






Let Them Code



Was there a setup cost to rework the main app into a base library? Sure. And

there was even more cost to make sure it was a good, easy-to-use library with

excellent documentation. But all of the productivity, cleanliness, and quality

benefits mean that all that work was a sound investment in a stable future with

a solid foundation to launch from.



Any time you feel like you're running up against a wall because, "Augh, it would

be so easy to fix in code, I just want to write some code here," the answer is

probably that you should be able to write your solution in code rather than

config. Just... make sure that code is your team's main language and not your

team's internally written "good-enough" config-garbage-slop-monster.

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
6 Quellen
CVE-2022-44255 | TOTOLINK LR350 9.3.5u.6369_B20220309 buffer overflow (EUVD-2022-47204)
2 Quellen
CVE-2026-68426 | Linux Kernel up to 6.18.41/7.1.5/7.2-rc3 xfrm validate_xmit_skb_list use after free (Nessus ID 346426)
1 Quelle
Windows 11 Probleme mit gültiger Domänenanmeldung nach September-Update [Workaround]
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Sentient Config is a Code Smell

Thematisch verwandte Begriffe: Sentient, Config, Code, Smell · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...