- Group tomcat, commons-lang3 version properties under spring-boot.version
- Drop thymeleaf override (PE-only dependency, not present in CE)
- Drop lz4 plumbing: kafka-clients 3.9.2 and cassandra-all 5.0.7 now transitively ship at.yawk.lz4:lz4-java, making the Dec 2025 CVE hack obsolete
AbstractTbQueueConsumerTemplate.poll() returned emptyList() immediately
when partitions was empty, bypassing both doPoll() and the secondary
sleep guard (which is also skipped for backends that report
isLongPollingSupported()==true, e.g. Kafka). The result was a
permanent CPU-burning loop on consumers whose partition assignment
ended up empty after a rebalance cascade — observed on 26
ie-downlink-consumer threads (~244% total CPU) until container restart.
Route the empty-partition path through sleepAndReturnEmpty() so the
caller honors durationInMillis regardless of long-polling support.
The alreadyProcessed() method used separate get() and put() calls on the
local cache, allowing concurrent threads in the notification executor pool
to both read null and bypass deduplication, creating duplicate notifications.
Replace with a single compute() call that atomically checks and updates
the cache entry, preventing the race between concurrent trigger processing.
Also fix: discard external cache timestamps that are more than 1 hour in
the future (clock skew protection), and avoid reading back from the SOFT
ref local cache when writing to external cache (GC could null it out).