Skip to content

Commit 3853e4b

Browse files
authored
ci: run NilAway package lints concurrently (#1329)
Runs up to four per-package NilAway checks at once while keeping the existing CPU and memory caps for each process. `NILAWAY_JOBS` remains configurable and rejects zero or invalid values so concurrency stays bounded. Each check writes to separate temporary output, which is printed in package order after the run. Output no longer streams, but all packages are checked before the target reports failure. Co-authored-by: Matthew Jacobs <mjacobs@users.noreply.github.com>
1 parent ecd0eba commit 3853e4b

1 file changed

Lines changed: 56 additions & 7 deletions

File tree

Makefile

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,20 +428,69 @@ nilaway-golangci-build:
428428
golangci-lint custom --version "$(GOLANGCI_LINT_VERSION)" --name custom-gcl
429429

430430
# Run NilAway through the custom golangci-lint module plugin.
431+
#
432+
# NilAway is run once per package instead of once over ./... because a single
433+
# whole-module run blows up memory. Each invocation therefore keeps its own
434+
# tight caps (GOMAXPROCS=1, GOGC=10, GOMEMLIMIT=512MiB). Those caps are
435+
# per-process, so the ~45 invocations can safely overlap: NILAWAY_JOBS of them
436+
# run at a time, bounding peak usage at roughly NILAWAY_JOBS x GOMEMLIMIT.
437+
# Concurrent invocations share one GOLANGCI_LINT_CACHE, so they need
438+
# --allow-parallel-runners; without it golangci-lint's start-up file lock makes
439+
# every overlapping run fail with "parallel golangci-lint is running".
440+
#
441+
# Each invocation writes its output to its own scratch file, which the parent
442+
# prints in package order once the run finishes. Writing straight to stdout
443+
# would interleave one package's findings with another's as soon as a report
444+
# exceeded the pipe's atomic-write size. NILAWAY_JOBS must be a positive
445+
# integer: `xargs -P 0` means "unlimited" and would remove the memory bound
446+
# this whole arrangement depends on.
447+
NILAWAY_JOBS ?= 4
448+
431449
nilaway: pricing-snapshot ensure-embed-dir nilaway-golangci-build
432450
@set -e; \
451+
case "$(NILAWAY_JOBS)" in \
452+
''|*[!0-9]*) \
453+
echo "nilaway: NILAWAY_JOBS must be a positive integer (got '$(NILAWAY_JOBS)')" >&2; \
454+
exit 1;; \
455+
esac; \
456+
njobs=$$(( $(NILAWAY_JOBS) + 0 )); \
457+
if [ "$$njobs" -lt 1 ]; then \
458+
echo "nilaway: NILAWAY_JOBS must be at least 1 (got '$(NILAWAY_JOBS)')" >&2; \
459+
exit 1; \
460+
fi; \
433461
root=$$(pwd); \
434462
dirs=$$(go list -f '{{.Dir}}' ./...); \
435-
for dir in $$dirs; do \
463+
pkgs=$$(for dir in $$dirs; do \
436464
if [ "$$dir" = "$$root" ]; then \
437-
pkg="."; \
465+
printf '%s\n' "."; \
438466
else \
439-
pkg="./$${dir#$$root/}"; \
467+
printf '%s\n' "./$${dir#$$root/}"; \
440468
fi; \
441-
echo "$(CUSTOM_GCL) run --config .golangci.nilaway.yml $$pkg"; \
442-
GOMAXPROCS=$${GOMAXPROCS:-1} GOGC=$${GOGC:-10} GOMEMLIMIT=$${GOMEMLIMIT:-512MiB} \
443-
$(CUSTOM_GCL) run --config .golangci.nilaway.yml "$$pkg"; \
444-
done
469+
done); \
470+
if [ -z "$$pkgs" ]; then echo "nilaway: no packages to lint" >&2; exit 1; fi; \
471+
NILAWAY_OUT_DIR=$$(mktemp -d); \
472+
export NILAWAY_OUT_DIR; \
473+
trap 'rm -f "$$NILAWAY_OUT_DIR"/*; rmdir "$$NILAWAY_OUT_DIR"' EXIT HUP INT TERM; \
474+
set +e; \
475+
printf '%s\n' "$$pkgs" | awk '{ printf "%d:%s\n", NR, $$0 }' | tr '\n' '\0' \
476+
| xargs -0 -n 1 -P "$$njobs" sh -c ' \
477+
n=$${1%%:*}; \
478+
pkg=$${1#*:}; \
479+
cmd="$(CUSTOM_GCL) run --allow-parallel-runners --config .golangci.nilaway.yml $$pkg"; \
480+
out=$$(GOMAXPROCS=$${GOMAXPROCS:-1} GOGC=$${GOGC:-10} GOMEMLIMIT=$${GOMEMLIMIT:-512MiB} \
481+
$(CUSTOM_GCL) run --allow-parallel-runners \
482+
--config .golangci.nilaway.yml "$$pkg" 2>&1); \
483+
status=$$?; \
484+
{ printf "%s\n" "$$cmd"; \
485+
if [ -n "$$out" ]; then printf "%s\n" "$$out"; fi; \
486+
} > "$$NILAWAY_OUT_DIR/$$n"; \
487+
exit $$status' sh; \
488+
rc=$$?; \
489+
set -e; \
490+
ls "$$NILAWAY_OUT_DIR" | sort -n | while IFS= read -r n; do \
491+
cat "$$NILAWAY_OUT_DIR/$$n"; \
492+
done; \
493+
exit $$rc
445494

446495
# Install pinned local lint tools.
447496
lint-tools:

0 commit comments

Comments
 (0)