99use Symfony \Component \Console \Attribute \AsCommand ;
1010use Workflow \V2 \Support \BackendCapabilities ;
1111use Workflow \V2 \Support \MatchingRoleSnapshot ;
12+ use Workflow \V2 \Support \RoleTopologySnapshot ;
1213
1314#[AsCommand(name: 'workflow:v2:doctor ' )]
1415class V2DoctorCommand extends Command
@@ -23,6 +24,7 @@ public function handle(): int
2324 {
2425 $ snapshot = BackendCapabilities::snapshot ();
2526 $ snapshot ['matching_role ' ] = MatchingRoleSnapshot::current ();
27+ $ snapshot ['topology ' ] = RoleTopologySnapshot::current ();
2628
2729 if ((bool ) $ this ->option ('json ' )) {
2830 try {
@@ -54,6 +56,7 @@ private function renderHumanSnapshot(array $snapshot): void
5456 $ this ->componentLine ('queue ' , $ snapshot ['queue ' ] ?? []);
5557 $ this ->componentLine ('cache ' , $ snapshot ['cache ' ] ?? []);
5658 $ this ->componentLine ('codec ' , $ snapshot ['codec ' ] ?? []);
59+ $ this ->topologyLine ($ snapshot ['topology ' ] ?? null );
5760 $ this ->matchingRoleLine ($ snapshot ['matching_role ' ] ?? null );
5861
5962 $ issues = $ snapshot ['issues ' ] ?? [];
@@ -132,4 +135,33 @@ private function matchingRoleLine(mixed $matchingRole): void
132135 $ dispatchMode ,
133136 ));
134137 }
138+
139+ private function topologyLine (mixed $ topology ): void
140+ {
141+ if (! is_array ($ topology )) {
142+ $ this ->line ('[INFO] topology: unavailable ' );
143+
144+ return ;
145+ }
146+
147+ $ shape = is_string ($ topology ['current_shape ' ] ?? null ) ? $ topology ['current_shape ' ] : 'unknown ' ;
148+ $ processClass = is_string ($ topology ['current_process_class ' ] ?? null )
149+ ? $ topology ['current_process_class ' ]
150+ : 'unknown ' ;
151+ $ executionMode = is_string ($ topology ['execution_mode ' ] ?? null )
152+ ? $ topology ['execution_mode ' ]
153+ : 'unknown ' ;
154+ $ roles = array_values (array_filter (
155+ is_array ($ topology ['current_roles ' ] ?? null ) ? $ topology ['current_roles ' ] : [],
156+ static fn (mixed $ role ): bool => is_string ($ role ) && $ role !== '' ,
157+ ));
158+
159+ $ this ->line (sprintf (
160+ '[INFO] topology: %s/%s (execution_mode=%s, roles=%s) ' ,
161+ $ shape ,
162+ $ processClass ,
163+ $ executionMode ,
164+ $ roles === [] ? 'none ' : implode (', ' , $ roles ),
165+ ));
166+ }
135167}
0 commit comments