11using System ;
2+ using System . Collections . Generic ;
23using System . Diagnostics ;
34using System . IO ;
4-
5+ using System . Text ;
56using BenchmarkDotNet . Configs ;
67using BenchmarkDotNet . Diagnosers ;
78using BenchmarkDotNet . Engines ;
89using BenchmarkDotNet . Loggers ;
910using BenchmarkDotNet . Running ;
1011using BenchmarkDotNet . Validators ;
1112
12- using JetBrains . Annotations ;
13-
1413namespace BenchmarkDotNet . Toolchains . InProcess
1514{
1615 /// <summary>Host API for in-process benchmarks.</summary>
1716 /// <seealso cref="IHost"/>
18- public sealed class InProcessHost : IHost
17+ internal sealed class InProcessHost : IHost
1918 {
2019 private readonly ILogger logger ;
21-
2220 private readonly IDiagnoser ? diagnoser ;
23-
2421 private readonly DiagnoserActionParameters ? diagnoserActionParameters ;
22+ private readonly List < string > inProcessDiagnoserLines = [ ] ;
2523
2624 /// <summary>Creates a new instance of <see cref="InProcessHost"/>.</summary>
2725 /// <param name="benchmarkCase">Current benchmark.</param>
@@ -34,7 +32,6 @@ public InProcessHost(BenchmarkCase benchmarkCase, ILogger logger, IDiagnoser dia
3432
3533 this . logger = logger ?? throw new ArgumentNullException ( nameof ( logger ) ) ;
3634 this . diagnoser = diagnoser ;
37- IsDiagnoserAttached = diagnoser != null ;
3835 Config = benchmarkCase . Config ;
3936
4037 if ( diagnoser != null )
@@ -44,16 +41,12 @@ public InProcessHost(BenchmarkCase benchmarkCase, ILogger logger, IDiagnoser dia
4441 default ) ;
4542 }
4643
47- /// <summary><c>True</c> if there are diagnosers attached.</summary>
48- /// <value><c>True</c> if there are diagnosers attached.</value>
49- [ PublicAPI ] public bool IsDiagnoserAttached { get ; }
50-
5144 /// <summary>Results of the run.</summary>
5245 /// <value>Results of the run.</value>
5346 public RunResults RunResults { get ; private set ; }
5447
5548 /// <summary>Current config</summary>
56- [ PublicAPI ] public IConfig Config { get ; set ; }
49+ public IConfig Config { get ; set ; }
5750
5851 /// <summary>Passes text to the host.</summary>
5952 /// <param name="message">Text to write.</param>
@@ -64,20 +57,18 @@ public InProcessHost(BenchmarkCase benchmarkCase, ILogger logger, IDiagnoser dia
6457
6558 /// <summary>Passes text (new line appended) to the host.</summary>
6659 /// <param name="message">Text to write.</param>
67- public void WriteLine ( string message ) => logger . WriteLine ( message ) ;
60+ public void WriteLine ( string message )
61+ {
62+ logger . WriteLine ( message ) ;
63+ if ( message . StartsWith ( CompositeInProcessDiagnoser . HeaderKey ) ) // Captures both header and results
64+ {
65+ inProcessDiagnoserLines . Add ( message ) ;
66+ }
67+ }
6868
6969 /// <summary>Sends notification signal to the host.</summary>
7070 /// <param name="hostSignal">The signal to send.</param>
71- public void SendSignal ( HostSignal hostSignal )
72- {
73- if ( ! IsDiagnoserAttached ) // no need to send the signal, nobody is listening for it
74- return ;
75-
76- if ( diagnoser == null )
77- throw new NullReferenceException ( nameof ( diagnoser ) ) ;
78-
79- diagnoser . Handle ( hostSignal , diagnoserActionParameters ) ;
80- }
71+ public void SendSignal ( HostSignal hostSignal ) => diagnoser ? . Handle ( hostSignal , diagnoserActionParameters ) ;
8172
8273 public void SendError ( string message ) => logger . WriteLine ( LogKind . Error , $ "{ ValidationErrorReporter . ConsoleErrorPrefix } { message } ") ;
8374
@@ -94,6 +85,34 @@ public void ReportResults(RunResults runResults)
9485 }
9586 }
9687
88+ // Keep in sync with Broker and WasmExecutor.
89+ internal void HandleInProcessDiagnoserResults ( BenchmarkCase benchmarkCase , CompositeInProcessDiagnoser compositeInProcessDiagnoser )
90+ {
91+ var linesEnumerator = inProcessDiagnoserLines . GetEnumerator ( ) ;
92+ while ( linesEnumerator . MoveNext ( ) )
93+ {
94+ // Something like "// InProcessDiagnoser 0 1"
95+ var line = linesEnumerator . Current ;
96+ string [ ] lineItems = line . Split ( ' ' ) ;
97+ int diagnoserIndex = int . Parse ( lineItems [ 2 ] ) ;
98+ int resultsLinesCount = int . Parse ( lineItems [ 3 ] ) ;
99+ var resultsStringBuilder = new StringBuilder ( ) ;
100+ for ( int i = 0 ; i < resultsLinesCount ; )
101+ {
102+ // Strip the prepended "// InProcessDiagnoserResults ".
103+ bool movedNext = linesEnumerator . MoveNext ( ) ;
104+ Debug . Assert ( movedNext ) ;
105+ line = linesEnumerator . Current . Substring ( CompositeInProcessDiagnoser . ResultsKey . Length + 1 ) ;
106+ resultsStringBuilder . Append ( line ) ;
107+ if ( ++ i < resultsLinesCount )
108+ {
109+ resultsStringBuilder . AppendLine ( ) ;
110+ }
111+ }
112+ compositeInProcessDiagnoser . DeserializeResults ( diagnoserIndex , benchmarkCase , resultsStringBuilder . ToString ( ) ) ;
113+ }
114+ }
115+
97116 public void Dispose ( )
98117 {
99118 // do nothing on purpose
0 commit comments