Add the async module

Every @Async behaviour that surprises people, asserted by a test and captured
to docs/output/: the self-invocation trap, what CGLIB cannot override, the
IllegalArgumentException a plain return type throws, the unbounded queue that
makes max-size decoration, spring.task.execution.propagate-context (new in
Boot 4.1.0), the two Executor beans that leave @Async on an unpooled
SimpleAsyncTaskExecutor, and JEP 491 measured on JDK 21 against JDK 25.
This commit is contained in:
2026-09-01 23:27:47 +05:30
commit 243cccd4ca
53 changed files with 1891 additions and 0 deletions

24
async/scripts/pinning-probe.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Runs PinningProbe with the virtual-thread scheduler limited to two carrier threads, so that
# pinning (if it happened) would serialise the work into visible seconds.
#
# The probe is compiled on its own with --release 21 rather than as part of the module, so the
# same class file can be run on a JDK 21 and a JDK 25 JVM. That comparison is the whole point:
# JEP 491 landed in JDK 24, and the difference between the two runs is the feature.
#
# Usage: scripts/pinning-probe.sh <path-to-javac> <path-to-java> [more java binaries...]
set -euo pipefail
cd "$(dirname "$0")/.."
JAVAC_BIN="${1:-javac}"
shift || true
OUT=target/probe-classes
mkdir -p "$OUT"
"$JAVAC_BIN" --release 21 -d "$OUT" src/main/java/com/ankurm/async/PinningProbe.java
for JAVA_BIN in "${@:-java}"; do
echo "---------------------------------------------------------------"
"$JAVA_BIN" \
-Djdk.virtualThreadScheduler.parallelism=2 \
-Djdk.virtualThreadScheduler.maxPoolSize=2 \
-cp "$OUT" com.ankurm.async.PinningProbe
done

21
async/scripts/run-all.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Regenerates every file under docs/output/. Nothing in this module's documentation, or in the
# article it accompanies, is typed by hand.
#
# scripts/run-all.sh # tests only
# scripts/run-all.sh /path/to/jdk21/bin/java # tests plus the JDK 21 vs JDK 25 pinning run
set -euo pipefail
cd "$(dirname "$0")/.."
mkdir -p docs/output
mvn -B test 2>&1 | grep -E 'Running |Tests run:|BUILD ' > docs/output/tests.txt
echo "wrote docs/output/tests.txt"
JAVA_BIN="$(command -v java)"
JAVAC_BIN="$(command -v javac)"
if [ $# -ge 1 ]; then
./scripts/pinning-probe.sh "$JAVAC_BIN" "$1" "$JAVA_BIN" > docs/output/pinning-probe.txt
else
./scripts/pinning-probe.sh "$JAVAC_BIN" "$JAVA_BIN" > docs/output/pinning-probe.txt
fi
echo "wrote docs/output/pinning-probe.txt"