Skip to content

Commit 164da91

Browse files
authored
Merge pull request #5 from sarustamyan-bdb/wcf-client-timing
Add timing on the client even if no behavior is configured on the service side
2 parents 6a904f9 + 63a3194 commit 164da91

File tree

2 files changed

+80
-77
lines changed

2 files changed

+80
-77
lines changed

MiniProfiler.WCF.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package>
33
<metadata>
44
<id>MiniProfiler.WCF</id>
5-
<version>3.0.12.1-wcffix-004</version>
5+
<version>3.0.12.1-wcffix-005</version>
66
<authors>Marc Gravell, Sam Saffron, Jarrod Dixon</authors>
77
<owners>Marc Gravell, Sam Saffron, Jarrod Dixon</owners>
88
<description>MiniProfiler integration for WCF</description>

StackExchange.Profiling.Wcf/WcfMiniProfilerClientInspector.cs

Lines changed: 79 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,6 @@ public class WcfMiniProfilerClientInspector : IClientMessageInspector
1616
/// </summary>
1717
private bool _http;
1818

19-
/// <summary>
20-
/// Initialises static members of the <see cref="WcfMiniProfilerClientInspector"/> class.
21-
/// </summary>
22-
static WcfMiniProfilerClientInspector()
23-
{
24-
GetCurrentProfiler = () => MiniProfiler.Current;
25-
}
26-
27-
/// <summary>
28-
/// Gets or sets the get current profiler.
29-
/// </summary>
30-
public static Func<MiniProfiler> GetCurrentProfiler { get; set; }
31-
3219
/// <summary>
3320
/// before the send request.
3421
/// </summary>
@@ -37,44 +24,51 @@ static WcfMiniProfilerClientInspector()
3724
/// <returns>the mini profiler start</returns>
3825
public object BeforeSendRequest(ref Message request, IClientChannel channel)
3926
{
40-
// If we currently are running inside a MiniProfiler context, then add a request onto this request
41-
var miniProfiler = GetCurrentProfiler();
42-
if (miniProfiler != null)
27+
var miniProfiler = MiniProfiler.Current;
28+
if (miniProfiler == null)
4329
{
44-
var header = new MiniProfilerRequestHeader
45-
{
46-
User = miniProfiler.User,
47-
ParentProfilerId = miniProfiler.Id
48-
};
30+
return null;
31+
}
4932

50-
// ReSharper disable PossibleUnintendedReferenceComparison
51-
if (request.Headers.MessageVersion != MessageVersion.None)
52-
// ReSharper restore PossibleUnintendedReferenceComparison
53-
{
54-
var untypedHeader = new MessageHeader<MiniProfilerRequestHeader>(header)
55-
.GetUntypedHeader(MiniProfilerRequestHeader.HeaderName, MiniProfilerRequestHeader.HeaderNamespace);
56-
request.Headers.Add(untypedHeader);
57-
}
58-
else if (_http || WebOperationContext.Current != null || channel.Via.Scheme == "http" | channel.Via.Scheme == "https")
59-
{
60-
_http = true;
33+
miniProfiler.Step($"WCF call to {channel.RemoteAddress.Uri}");
6134

62-
if (!request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
63-
{
64-
request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
65-
}
66-
HttpRequestMessageProperty property = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
35+
var header = new MiniProfilerRequestHeader
36+
{
37+
User = miniProfiler.User,
38+
ParentProfilerId = miniProfiler.Id
39+
};
6740

68-
property.Headers.Add(MiniProfilerRequestHeader.HeaderName, header.ToHeaderText());
69-
}
70-
else
71-
throw new InvalidOperationException("MVC Mini Profiler does not support EnvelopeNone unless HTTP is the transport mechanism");
41+
// ReSharper disable PossibleUnintendedReferenceComparison
42+
if (request.Headers.MessageVersion != MessageVersion.None)
43+
// ReSharper restore PossibleUnintendedReferenceComparison
44+
{
45+
var untypedHeader = new MessageHeader<MiniProfilerRequestHeader>(header)
46+
.GetUntypedHeader(MiniProfilerRequestHeader.HeaderName, MiniProfilerRequestHeader.HeaderNamespace);
47+
request.Headers.Add(untypedHeader);
48+
}
49+
else if (_http || WebOperationContext.Current != null || channel.Via.Scheme == "http" || channel.Via.Scheme == "https")
50+
{
51+
_http = true;
7252

73-
// Can't use MiniProfiler.DurationMilliseconds as it is set only when the profiler is stopped
74-
return new MiniProfilerStart { StartTime = miniProfiler.GetElapsedMilliseconds() };
53+
object property;
54+
if (!request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out property))
55+
{
56+
property = new HttpRequestMessageProperty();
57+
request.Properties.Add(HttpRequestMessageProperty.Name, property);
58+
}
59+
((HttpRequestMessageProperty)property).Headers.Add(MiniProfilerRequestHeader.HeaderName, header.ToHeaderText());
60+
}
61+
else
62+
{
63+
throw new InvalidOperationException("MVC Mini Profiler does not support EnvelopeNone unless HTTP is the transport mechanism");
7564
}
7665

77-
return null;
66+
return new MiniProfilerState
67+
{
68+
Timing = miniProfiler.Head,
69+
// Can't use MiniProfiler.DurationMilliseconds as it is set only when the profiler is stopped
70+
StartTime = miniProfiler.GetElapsedMilliseconds()
71+
};
7872
}
7973

8074
/// <summary>
@@ -84,53 +78,62 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel)
8478
/// <param name="correlationState">The correlation state.</param>
8579
public void AfterReceiveReply(ref Message reply, object correlationState)
8680
{
87-
var profilerStart = correlationState as MiniProfilerStart;
81+
var profilerState = correlationState as MiniProfilerState;
8882

89-
// Check to see if there are any results here
90-
var profiler = GetCurrentProfiler();
91-
if (profiler != null)
83+
if (profilerState == null || profilerState.Timing == null)
9284
{
93-
// Check to see if we have a request as part of this message
94-
MiniProfilerResultsHeader resultsHeader = null;
95-
// ReSharper disable PossibleUnintendedReferenceComparison
96-
if (reply.Headers.MessageVersion != MessageVersion.None)
97-
// ReSharper restore PossibleUnintendedReferenceComparison
85+
return;
86+
}
87+
// Check to see if we have a request as part of this message
88+
MiniProfilerResultsHeader resultsHeader = null;
89+
// ReSharper disable PossibleUnintendedReferenceComparison
90+
if (reply.Headers.MessageVersion != MessageVersion.None)
91+
// ReSharper restore PossibleUnintendedReferenceComparison
92+
{
93+
var headerIndex = reply.Headers.FindHeader(MiniProfilerResultsHeader.HeaderName, MiniProfilerResultsHeader.HeaderNamespace);
94+
if (headerIndex >= 0)
9895
{
99-
var headerIndex = reply.Headers.FindHeader(MiniProfilerResultsHeader.HeaderName, MiniProfilerResultsHeader.HeaderNamespace);
100-
if (headerIndex >= 0)
101-
resultsHeader = reply.Headers.GetHeader<MiniProfilerResultsHeader>(headerIndex);
96+
resultsHeader = reply.Headers.GetHeader<MiniProfilerResultsHeader>(headerIndex);
10297
}
103-
else if (_http || reply.Properties.ContainsKey(HttpResponseMessageProperty.Name))
104-
{
105-
_http = true;
106-
107-
var property = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
98+
}
99+
else if (_http || reply.Properties.ContainsKey(HttpResponseMessageProperty.Name))
100+
{
101+
_http = true;
108102

109-
var text = property.Headers[MiniProfilerResultsHeader.HeaderName];
110-
if (!string.IsNullOrEmpty(text))
111-
resultsHeader = MiniProfilerResultsHeader.FromHeaderText(text);
112-
}
113-
else
114-
throw new InvalidOperationException("MVC Mini Profiler does not support EnvelopeNone unless HTTP is the transport mechanism");
103+
var property = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
115104

116-
if (resultsHeader != null && resultsHeader.ProfilerResults != null)
105+
var text = property.Headers[MiniProfilerResultsHeader.HeaderName];
106+
if (!string.IsNullOrEmpty(text))
117107
{
118-
// Update timings of profiler results
119-
if (profilerStart != null)
120-
resultsHeader.ProfilerResults.Root.UpdateStartMillisecondTimingsToAbsolute(profilerStart.StartTime);
121-
122-
profiler.AddProfilerResults(resultsHeader.ProfilerResults);
108+
resultsHeader = MiniProfilerResultsHeader.FromHeaderText(text);
123109
}
124110
}
111+
else
112+
{
113+
throw new InvalidOperationException("MVC Mini Profiler does not support EnvelopeNone unless HTTP is the transport mechanism");
114+
}
115+
116+
if (null != resultsHeader && null != resultsHeader.ProfilerResults)
117+
{
118+
resultsHeader.ProfilerResults.Root.UpdateStartMillisecondTimingsToAbsolute(profilerState.StartTime);
119+
profilerState.Timing.AddChild(resultsHeader.ProfilerResults.Root);
120+
}
121+
122+
profilerState.Timing.Stop();
125123
}
126124

127125
/// <summary>
128-
/// The mini profiler start.
126+
/// The mini profiler state before the WCF call.
129127
/// </summary>
130-
private class MiniProfilerStart
128+
private class MiniProfilerState
131129
{
132130
/// <summary>
133-
/// Gets or sets the start time.
131+
/// Gets or sets the timing within which the WCF call was made.
132+
/// </summary>
133+
public Timing Timing { get; set; }
134+
135+
/// <summary>
136+
/// Gets or sets the number of miliseconds between the start of profiler and the beginning of the WCF call.
134137
/// </summary>
135138
public decimal StartTime { get; set; }
136139
}

0 commit comments

Comments
 (0)