Alt account of @Badabinski

Just a sweaty nerd interested in software, home automation, emotional issues, and polite discourse about all of the above.

  • 0 Posts
  • 14 Comments
Joined 7 months ago
cake
Cake day: June 9th, 2024

help-circle

  • This is why you don’t use battery chemistries that can thermally run away autoignite in grid storage. The plant was using LG JH4 batteries, which use an NMC chemistry. I don’t think that LiFePO4 cells were as ubiquitous when this plant was first constructed, so the designers opted for something spicy instead.

    This shit is why you use LiFePO4. It can’t thermally run away autoignite, it lasts longer, and the reduced energy density doesn’t really matter for grid storage. Plus, it doesn’t use nickel or cobalt so the only conflict resource is lithium.

    EDIT: LiFePO4 batteries can enter thermal runaway, but they can’t autoignite.


  • We lack the materials and engineering necessary to make lifted weight storage systems enter the order of magnitude of energy storage needed to compete with batteries, let alone pumped hydro. It’s just really, really hard to compete with literal megatons of water pumped up a 500 meter slope.

    I believe that the plant in question was using something besides Lithium Iron Phosphate batteries. This press release mentions LG JH4 which are deffo not LiFePO4. LiFePO4 batteries are far, far safer than other Lithium chemistries, and are now the norm for BESS (not cars tho, since they have lower energy density but better a better lifetime than NMC/NCA). This fire would not have happened with a BESS using LiFePO4 batteries.

    Now that batteries with aqueous sodium-ion chemistries are becoming available, we should begin transitioning pre-LiFePO4 sites to those wholesale. Aqueous sodium-ion batteries should be even safer than LiFePO4, and while they have kinda shit energy density, they’re still fine for grid storage.

    EDIT: correction, LiFePO4 batteries can run away, but they are incapable of autoignition.


  • This is why I made the reference to Go. I honestly hate Go, I think exceptions are great and very ergonomic and I wish that language had not become so popular. However, a whole shitload of people apparently disagree, hence the popularity of Go and the acceptance of its (imo) terrible error handling. If developers don’t have a problem with it in Go, I don’t see why they’d have a problem with it in Bash. The error handling is identical to what I posted and the syntax is shockingly similar. You must unpack the return of a func in Go if you’re going to assign, but you’re totally free to just assign an err to _ in Go and be on your way, just like you can ignore errors in Bash. The objectively correct way to write Go is to handle every err that gets returned to you, either by doing something, or passing it up the stack (and possibly wrapping it). It’s a bunch of bubbling up. My scripts end up being that way too. It’s messy, but I’ve found it to be an incredibly reliable strategy. Plus, it’s really easy for me to grep for a log message and get the exact line where I encountered an issue.

    This is all just my opinion. I think this is one of those things where the best option is to just agree to disagree. I will admit that it irritates me to see blanket statements saying “your script is bad if you don’t set -euo pipefail”, but I’d be totally fine if more people made a measured recommendation like you did. I likely will never use set -e, but if it gets the bills paid for people then that’s fine. I just think people need to be warned of the footguns.

    EDIT: my autocorrect really wanted to fuck up this comment for some reason. Apologies if I have a dumb number of typos.




  • I personally don’t believe there’s a case for it in the scripts I write, but I’ve spent years building the || die habit to the point where I don’t even think about it as I’m writing. I’ll probably edit my post to be a little less absolute, now that I’m awake and have some caffeine in me.

    One other benefit I forgot to mention to explicit error handling is that you get to actually log a useful error message. Being able to rg 'failed to scrozzle foo.* because service y was not available' and immediately find the exact line in the script that failed is so nice. It’s not quite a stack trace with line numbers, but it’s much nicer than what you have with bash by default or with set -e.



  • From https://mywiki.wooledge.org/BashFAQ/105

    Once upon a time, a man with a dirty lab coat and long, uncombed hair showed up at the town police station, demanding to see the chief of police. “I’ve done it!” he exclaimed. “I’ve built the perfect criminal-catching robot!”

    The police chief was skeptical, but decided that it might be worth the time to see what the man had invented. Also, he secretly thought, it might be a somewhat unwise move to completely alienate the mad scientist and his army of hunter robots.

    So, the man explained to the police chief how his invention could tell the difference between a criminal and law-abiding citizen using a series of heuristics. “It’s especially good at spotting recently escaped prisoners!” he said. “Guaranteed non-lethal restraints!”

    Frowning and increasingly skeptical, the police chief nevertheless allowed the man to demonstrate one robot for a week. They decided that the robot should patrol around the jail. Sure enough, there was a jailbreak a few days later, and an inmate digging up through the ground outside of the prison facility was grabbed by the robot and carried back inside the prison.

    The surprised police chief allowed the robot to patrol a wider area. The next day, the chief received an angry call from the zookeeper. It seems the robot had cut through the bars of one of the animal cages, grabbed the animal, and delivered it to the prison.

    The chief confronted the robot’s inventor, who asked what animal it was. “A zebra,” replied the police chief. The man slapped his head and exclaimed, “Curses! It was fooled by the black and white stripes! I shall have to recalibrate!” And so the man set about rewriting the robot’s code. Black and white stripes would indicate an escaped inmate UNLESS the inmate had more than two legs. Then it should be left alone.

    The robot was redeployed with the updated code, and seemed to be operating well enough for a few days. Then on Saturday, a mob of children in soccer clothing, followed by their parents, descended on the police station. After the chaos subsided, the chief was told that the robot had absconded with the referee right in the middle of a soccer game.

    Scowling, the chief reported this to the scientist, who performed a second calibration. Black and white stripes would indicate an escaped inmate UNLESS the inmate had more than two legs OR had a whistle on a necklace.

    Despite the second calibration, the police chief declared that the robot would no longer be allowed to operate in his town. However, the news of the robot had spread, and requests from many larger cities were pouring in. The inventor made dozens more robots, and shipped them off to eager police stations around the nation. Every time a robot grabbed something that wasn’t an escaped inmate, the scientist was consulted, and the robot was recalibrated.

    Unfortunately, the inventor was just one man, and he didn’t have the time or the resources to recalibrate EVERY robot whenever one of them went awry. The robot in Shangri-La was recalibrated not to grab a grave-digger working on a cold winter night while wearing a ski mask, and the robot in Xanadu was recalibrated not to capture a black and white television set that showed a movie about a prison break, and so on. But the robot in Xanadu would still grab grave-diggers with ski masks (which it turns out was not common due to Xanadu’s warmer climate), and the robot in Shangri-La was still a menace to old televisions (of which there were very few, the people of Shangri-La being on the average more wealthy than those of Xanadu).

    So, after a few years, there were different revisions of the criminal-catching robot in most of the major cities. In some places, a clever criminal could avoid capture by wearing a whistle on a string around the neck. In others, one would be well-advised not to wear orange clothing in certain rural areas, no matter how close to the Harvest Festival it was, unless one also wore the traditional black triangular eye-paint of the Pumpkin King.

    Many people thought, “This is lunacy!” But others thought the robots did more good than harm, all things considered, and so in some places the robots are used, while in other places they are shunned.

    The end.


  • The issue with set -e is that it’s hideously broken and inconsistent. Let me copy the examples from the wiki I linked.


    Or, “so you think set -e is OK, huh?”

    Exercise 1: why doesn’t this example print anything?

    #!/usr/bin/env bash
    set -e
    i=0
    let i++
    echo "i is $i"
    

    Exercise 2: why does this one sometimes appear to work? In which versions of bash does it work, and in which versions does it fail?

    #!/usr/bin/env bash
    set -e
    i=0
    ((i++))
    echo "i is $i"
    

    Exercise 3: why aren’t these two scripts identical?

    #!/usr/bin/env bash
    set -e
    test -d nosuchdir && echo no dir
    echo survived 
    
    #!/usr/bin/env bash
    set -e
    f() { test -d nosuchdir && echo no dir; }
    f
    echo survived
    

    Exercise 4: why aren’t these two scripts identical?

    set -e
    f() { test -d nosuchdir && echo no dir; }
    f
    echo survived
    
    set -e
    f() { if test -d nosuchdir; then echo no dir; fi; }
    f
    echo survived
    

    Exercise 5: under what conditions will this fail?

    set -e
    read -r foo < configfile
    

    And now, back to your regularly scheduled comment reply.

    set -e would absolutely be more elegant if it worked in a way that was easy to understand. I would be shouting its praises from my rooftop if it could make Bash into less of a pile of flaming plop. Unfortunately , set -e is, by necessity, a labyrinthian mess of fucked up hacks.

    Let me leave you with a allegory about set -e copied directly from that same wiki page. It’s too long for me to post it in this comment, so I’ll respond to myself.


  • I was tempted for years to use it as an occasional try/catch, but learning Go made me realize that exceptions are amazing and I miss them, but that it is possible (but occasionally hideously tedious) to write software without them. Like, I feel like anyone who has written Go competently (i.e. they handle every returned err on an individual or aggregated basis) should be able to write relatively error-handled shell. There are still the billion other footguns built directly into bash that will destroy hopes and dreams, but handling errors isn’t too bad if you just have a little die function and the determination to use it.




  • set -euo pipefail is, in my opinion, an antipattern. This page does a really good job of explaining why. pipefail is occasionally useful, but should be toggled on and off as needed, not left on. IMO, people should just write shell the way they write go, handling every command that could fail individually. it’s easy if you write a die function like this:

    die () {
      message="$1"; shift
      return_code="${1:-1}"
      printf '%s\n' "$message" 1>&2
      exit "$return_code"
    }
    
    # we should exit if, say, cd fails
    cd /tmp || die "Failed to cd /tmp while attempting to scrozzle foo $foo"
    # downloading something? handle the error. Don't like ternary syntax? use if
    if ! wget https://someheinousbullshit.com/"$foo"; then
      die "failed to get unscrozzled foo $foo"
    fi
    

    It only takes a little bit of extra effort to handle the errors individually, and you get much more reliable shell scripts. To replace -u, just use shellcheck with your editor when writing scripts. I’d also highly recommend https://mywiki.wooledge.org/ as a resource for all things POSIX shell or Bash.