Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-25 07:40:13 +01:00
Record circular dependencies
Dieser Commit ist enthalten in:
Ursprung
1856fb6aad
Commit
2d54a2c15b
@ -6,7 +6,9 @@ import com.google.common.graph.GraphBuilder;
|
|||||||
import com.google.common.graph.MutableGraph;
|
import com.google.common.graph.MutableGraph;
|
||||||
import com.velocitypowered.api.plugin.PluginDescription;
|
import com.velocitypowered.api.plugin.PluginDescription;
|
||||||
import com.velocitypowered.api.plugin.meta.PluginDependency;
|
import com.velocitypowered.api.plugin.meta.PluginDependency;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -53,27 +55,38 @@ public class PluginDependencyUtils {
|
|||||||
Map<PluginDescription, Mark> marks = new HashMap<>();
|
Map<PluginDescription, Mark> marks = new HashMap<>();
|
||||||
|
|
||||||
for (PluginDescription node : graph.nodes()) {
|
for (PluginDescription node : graph.nodes()) {
|
||||||
visitNode(graph, node, marks, sorted);
|
visitNode(graph, node, marks, sorted, new ArrayDeque<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void visitNode(Graph<PluginDescription> dependencyGraph, PluginDescription node,
|
private static void visitNode(Graph<PluginDescription> dependencyGraph, PluginDescription node,
|
||||||
Map<PluginDescription, Mark> marks, List<PluginDescription> sorted) {
|
Map<PluginDescription, Mark> marks, List<PluginDescription> sorted,
|
||||||
|
Deque<PluginDescription> currentIteration) {
|
||||||
Mark mark = marks.getOrDefault(node, Mark.NOT_VISITED);
|
Mark mark = marks.getOrDefault(node, Mark.NOT_VISITED);
|
||||||
if (mark == Mark.PERMANENT) {
|
if (mark == Mark.PERMANENT) {
|
||||||
return;
|
return;
|
||||||
} else if (mark == Mark.TEMPORARY) {
|
} else if (mark == Mark.TEMPORARY) {
|
||||||
throw new IllegalStateException("Improper plugin dependency graph");
|
// A circular dependency has been detected.
|
||||||
|
currentIteration.addLast(node);
|
||||||
|
StringBuilder loopGraph = new StringBuilder();
|
||||||
|
for (PluginDescription description : currentIteration) {
|
||||||
|
loopGraph.append(description.getId());
|
||||||
|
loopGraph.append(" -> ");
|
||||||
|
}
|
||||||
|
loopGraph.setLength(loopGraph.length() - 4);
|
||||||
|
throw new IllegalStateException("Circular dependency detected: " + loopGraph.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentIteration.addLast(node);
|
||||||
marks.put(node, Mark.TEMPORARY);
|
marks.put(node, Mark.TEMPORARY);
|
||||||
for (PluginDescription edge : dependencyGraph.successors(node)) {
|
for (PluginDescription edge : dependencyGraph.successors(node)) {
|
||||||
visitNode(dependencyGraph, edge, marks, sorted);
|
visitNode(dependencyGraph, edge, marks, sorted, currentIteration);
|
||||||
}
|
}
|
||||||
|
|
||||||
marks.put(node, Mark.PERMANENT);
|
marks.put(node, Mark.PERMANENT);
|
||||||
|
currentIteration.removeLast();
|
||||||
sorted.add(node);
|
sorted.add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren