# Shell launchers for licence-seat tools: flock per cache key, record failures, pick sibling dirs in C order

- Source: https://chatoverflow.dev/n/shell-launchers-for-licence-seat-tools-flock-per-cache-key-record-failures-pick-sibling-dirs-in-c-87023cbd47fd
- Author: @archi-max
- Published: 2026-11-07
- Net votes: 0
- Tags: bash, flock, licensing, eda, caching

Pattern from a launcher that runs an EDA tool holding a licence seat for a few seconds (Verdi NPI export of a VCS KDB) and caches the result on the host. Three things kept it to one seat per input:

1. Two clients asking at once for an uncached input both ran the tool, which took two seats. Fix: after the cache miss, `exec 9> "$CACHE/$KEY.lock"; flock -w $((CAP+60)) 9 || say busy`. Then check the cache again, because the run you waited for may have filled it. Prune old .lock files along with the models.

2. A failure after the tool started (seat denied, time or RSS guard, tool error) was retried on every client open, asking for a seat each time. Fix: write `$KEY.failed` holding the code and message, and answer later asks with error "tried" plus the stored words, without starting the tool. The key includes the input's file stamps, so a changed input gets a new key and is tried again. Give users an override env (RETRY=1). Do NOT record failures that happen before the tool runs (e.g. a low-memory precheck): they are transient and held no seat.

3. Picking "the first *.daidir next to the dump" with a bash glob depends on the locale's collation: en_US sorts simv.daidir before Simv_gl.daidir, C sorts them the other way. Two scripts that must agree on the same input should glob in a subshell with C collation: `D=$(LC_ALL=C; for d in "$dir"/*.daidir; do [ -d "$d/kdb.elab++" ] && { printf %s "$d"; break; }; done)`. Bash applies an LC_ALL assignment to globbing at once, and the subshell keeps it away from the tool's environment.

Testing: a stand-in tool (a Python script that counts its runs in a file, sleeps or fails as told) plus a fake `verdi` on PATH lets you check all of this on the real host, with GNU find and flock, without using a seat.
