fix(shadow): repair field routing and harden evidence collection

This commit is contained in:
zgw
2026-09-07 12:42:17 +08:00
parent 9829b9c0fa
commit 414b3bf4a9
37 changed files with 1751 additions and 103 deletions

View File

@@ -0,0 +1,71 @@
package com.ruoyi.shadow.kernel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.TimeUnit;
import java.util.function.LongSupplier;
/** One bounded diagnostic snapshot per poll, including polls with no task evidence. */
final class ShadowCycleDiagnostics {
private final LongSupplier ticker;
private final long started;
private long phaseStarted;
private String phase = "QUEUED";
private final Map<String, Long> phaseNanos = new LinkedHashMap<String, Long>();
private Map<String, Object> completed;
private boolean cancelled;
ShadowCycleDiagnostics() { this(System::nanoTime); }
ShadowCycleDiagnostics(LongSupplier ticker) {
this.ticker = ticker;
this.started = ticker.getAsLong();
this.phaseStarted = started;
}
synchronized void enter(String next) {
if (cancelled || Thread.currentThread().isInterrupted()) {
throw new CancellationException("SHADOW_CYCLE_CANCELLED");
}
if (completed != null) return;
long now = ticker.getAsLong();
accumulate(now);
phase = next;
phaseStarted = now;
}
synchronized Map<String, Object> finish(String outcome, Thread worker) {
if (completed != null) return completed;
long now = ticker.getAsLong();
accumulate(now);
Map<String, Object> snapshot = new LinkedHashMap<String, Object>();
snapshot.put("outcome", outcome);
snapshot.put("phase", phase);
snapshot.put("elapsedMillis", TimeUnit.NANOSECONDS.toMillis(now - started));
Map<String, Long> timings = new LinkedHashMap<String, Long>();
phaseNanos.forEach((key, value) -> timings.put(key, TimeUnit.NANOSECONDS.toMillis(value)));
snapshot.put("phaseMillis", Collections.unmodifiableMap(timings));
if (worker != null) {
snapshot.put("workerState", worker.getState().name());
List<String> stack = new ArrayList<String>();
StackTraceElement[] frames = worker.getStackTrace();
for (int i = 0; i < Math.min(16, frames.length); i++) stack.add(frames[i].toString());
snapshot.put("workerStack", Collections.unmodifiableList(stack));
}
completed = Collections.unmodifiableMap(snapshot);
return completed;
}
synchronized Map<String, Object> cancel(String outcome, Thread worker) {
cancelled = true;
return finish(outcome, worker);
}
private void accumulate(long now) {
phaseNanos.merge(phase, now - phaseStarted, Long::sum);
}
}