fix(shadow): respect queue phases and compress input evidence

This commit is contained in:
zgw
2026-09-08 11:23:50 +08:00
parent 414b3bf4a9
commit af8b5f1830
40 changed files with 1035 additions and 46 deletions

View File

@@ -18,6 +18,7 @@ final class ShadowCycleDiagnostics {
private final Map<String, Long> phaseNanos = new LinkedHashMap<String, Long>();
private Map<String, Object> completed;
private boolean cancelled;
private Map<String, Object> dispatch = Collections.emptyMap();
ShadowCycleDiagnostics() { this(System::nanoTime); }
@@ -27,6 +28,43 @@ final class ShadowCycleDiagnostics {
this.phaseStarted = started;
}
synchronized void dispatch(com.ruoyi.shadow.facts.ShadowFactBatch batch,
com.ruoyi.wcs.application.dispatch.DispatchSnapshot snapshot,
com.ruoyi.wcs.application.dispatch.DispatchCycleResult result) {
if (completed != null || cancelled) return;
Map<String, Object> values = new LinkedHashMap<String, Object>();
values.put("eligiblePhases", snapshot.getReadySteps().size());
values.put("granted", result.getGranted().size());
values.put("held", result.getHeld().size());
values.put("yielded", result.getYielded().size());
Map<String, Integer> observations = new LinkedHashMap<String, Integer>();
for (com.ruoyi.shadow.facts.ShadowQueueFact queue : batch.getQueues()) {
if (!queue.isActive()) continue;
String reason = com.ruoyi.shadow.facts.ShadowQueueDispatchEligibility.observationReason(queue, batch);
if (reason != null) observations.merge(reason, 1, Integer::sum);
}
values.put("observations", Collections.unmodifiableMap(observations));
int safe = 0;
for (String id : snapshot.getTopology().getNodeIds()) {
com.ruoyi.wcs.domain.topology.TopologyNode node = snapshot.getTopology().node(id);
if (node.isSafeWait() || node.isSafeYield()) safe++;
}
values.put("validatedSafePointCount", safe);
values.put("safePointStatus", safe == 0 ? "UNCONFIGURED" : "TOPOLOGY_VALIDATED");
List<Map<String, Object>> holds = new ArrayList<Map<String, Object>>();
for (com.ruoyi.wcs.application.dispatch.HeldDispatch hold : result.getHeld()) {
if (holds.size() == 20) break;
Map<String, Object> row = new LinkedHashMap<String, Object>();
row.put("taskId", hold.getOrderId()); row.put("vehicleId", hold.getVehicleId());
row.put("reasonCode", hold.getReasonCode());
List<String> blockers = new ArrayList<String>(hold.getBlockingVehicleIds());
row.put("blockingVehicleIds", Collections.unmodifiableList(blockers.subList(0, Math.min(20, blockers.size()))));
holds.add(Collections.unmodifiableMap(row));
}
values.put("holdSamples", Collections.unmodifiableList(holds));
dispatch = Collections.unmodifiableMap(values);
}
synchronized void enter(String next) {
if (cancelled || Thread.currentThread().isInterrupted()) {
throw new CancellationException("SHADOW_CYCLE_CANCELLED");
@@ -49,6 +87,7 @@ final class ShadowCycleDiagnostics {
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));
snapshot.put("dispatch", dispatch);
if (worker != null) {
snapshot.put("workerState", worker.getState().name());
List<String> stack = new ArrayList<String>();