1010import java .util .Set ;
1111import java .util .stream .Collectors ;
1212
13+ import org .jboss .logging .Logger ;
14+
1315import io .quarkus .arc .deployment .ArcConfig ;
1416import io .quarkus .arc .deployment .CompletedApplicationClassPredicateBuildItem ;
1517import io .quarkus .arc .deployment .ValidationPhaseBuildItem ;
2931
3032public class ArcDevModeApiProcessor {
3133
34+ private static final Logger LOG = Logger .getLogger (ArcDevModeApiProcessor .class );
35+
36+ /**
37+ * Do not generate dependency graphs for apps with more than N beans
38+ */
39+ private static final int DEPENCENY_GRAPH_BEANS_LIMIT = 1000 ;
40+
41+ /**
42+ * If a dependency graph exceeds the limit then we apply the {@link DevBeanInfos#MAX_DEPENDENCY_LEVEL} and if still exceeds
43+ * the limit it's skipped completely, i.e. dependency graph is not available
44+ */
45+ private static final int DEPENCENY_GRAPH_NODES_LIMIT = 30 ;
46+
3247 @ BuildStep (onlyIf = IsDevelopment .class )
3348 public void collectBeanInfo (ArcConfig config , ValidationPhaseBuildItem validationPhaseBuildItem ,
3449 CompletedApplicationClassPredicateBuildItem predicate ,
@@ -65,7 +80,7 @@ public void collectBeanInfo(ArcConfig config, ValidationPhaseBuildItem validatio
6580
6681 // Build dependency graphs
6782 Map <String , List <String >> beanDependenciesMap = new HashMap <>();
68- if (config . devMode (). generateDependencyGraphs ()) {
83+ if (generateDependencyGraphs (config , beanInfos )) {
6984 BeanResolver resolver = validationPhaseBuildItem .getBeanResolver ();
7085 Collection <BeanInfo > beans = validationContext .get (BuildExtension .Key .BEANS );
7186 Map <BeanInfo , List <InjectionPointInfo >> directDependents = new HashMap <>();
@@ -85,11 +100,27 @@ public void collectBeanInfo(ArcConfig config, ValidationPhaseBuildItem validatio
85100 DependencyGraph dependencyGraph = buildDependencyGraph (bean , validationContext , resolver , beanInfos ,
86101 allInjectionPoints , declaringToProducers ,
87102 directDependents );
103+ if (dependencyGraph .links .isEmpty ()) {
104+ // Skip the graph if no links exist
105+ continue ;
106+ }
107+ if (dependencyGraph .nodes .size () > DEPENCENY_GRAPH_NODES_LIMIT ) {
108+ DependencyGraph visibleGraph = dependencyGraph .forLevel (DevBeanInfos .DEFAULT_MAX_DEPENDENCY_LEVEL );
109+ if (visibleGraph .nodes .size () > DEPENCENY_GRAPH_NODES_LIMIT ) {
110+ LOG .debugf ("Skip dependency graph for %s - too many visible nodes: %s" , bean ,
111+ visibleGraph .nodes .size ());
112+ continue ;
113+ } else {
114+ LOG .debugf ("Dependency graph for %s was reduced to visible nodes: %s" , bean ,
115+ dependencyGraph .nodes .size ());
116+ dependencyGraph = visibleGraph ;
117+ }
118+ }
88119 beanInfos .addDependencyGraph (bean .getIdentifier (), dependencyGraph );
89120 // id -> [dep1Id, dep2Id]
90121 beanDependenciesMap .put (bean .getIdentifier (),
91122 dependencyGraph .filterLinks (link -> link .type .equals ("directDependency" )).nodes .stream ()
92- .map (DevBeanInfo ::getId ).filter (id -> !id .equals (bean .getIdentifier ()))
123+ .map (Node ::getId ).filter (id -> !id .equals (bean .getIdentifier ()))
93124 .collect (Collectors .toList ()));
94125 }
95126 }
@@ -111,7 +142,7 @@ DependencyGraph buildDependencyGraph(BeanInfo bean, ValidationContext validation
111142 addNodesDependencies (0 , bean , nodes , links , bean , devBeanInfos );
112143 addNodesDependents (0 , bean , nodes , links , bean , allInjectionPoints , declaringToProducers , resolver , devBeanInfos ,
113144 directDependents );
114- return new DependencyGraph (nodes , links );
145+ return new DependencyGraph (nodes . stream (). map ( Node :: from ). collect ( Collectors . toSet ()) , links );
115146 }
116147
117148 private void addNodesDependencies (int level , BeanInfo root , Set <DevBeanInfo > nodes , Set <Link > links , BeanInfo bean ,
@@ -184,4 +215,13 @@ private void addNodesDependents(int level, BeanInfo root, Set<DevBeanInfo> nodes
184215 }
185216 }
186217
218+ private boolean generateDependencyGraphs (ArcConfig config , DevBeanInfos beanInfos ) {
219+ return switch (config .devMode ().generateDependencyGraphs ()) {
220+ case TRUE -> true ;
221+ case FALSE -> false ;
222+ case AUTO -> beanInfos .getBeans ().size () < DEPENCENY_GRAPH_BEANS_LIMIT ;
223+ default -> throw new IllegalArgumentException ("Unexpected value: " + config .devMode ().generateDependencyGraphs ());
224+ };
225+ }
226+
187227}
0 commit comments