added stats with number of active native calls, useful for debugging

pull/1445/head
Jan Tattermusch 10 years ago
parent 618647dc74
commit 1b54fcf31b
  1. 4
      src/csharp/Grpc.Core/Grpc.Core.csproj
  2. 16
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  3. 6
      src/csharp/Grpc.Core/Internal/AsyncCall.cs
  4. 5
      src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
  5. 6
      src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
  6. 61
      src/csharp/Grpc.Core/Internal/AtomicCounter.cs
  7. 45
      src/csharp/Grpc.Core/Internal/DebugStats.cs

@ -5,7 +5,7 @@
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion> <ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</ProjectGuid> <ProjectGuid>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
@ -94,6 +94,8 @@
<Compile Include="Internal\ClientResponseStream.cs" /> <Compile Include="Internal\ClientResponseStream.cs" />
<Compile Include="Internal\ServerRequestStream.cs" /> <Compile Include="Internal\ServerRequestStream.cs" />
<Compile Include="Internal\ServerResponseStream.cs" /> <Compile Include="Internal\ServerResponseStream.cs" />
<Compile Include="Internal\AtomicCounter.cs" />
<Compile Include="Internal\DebugStats.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />

@ -86,6 +86,8 @@ namespace Grpc.Core
{ {
instance.Close(); instance.Close();
instance = null; instance = null;
CheckDebugStats();
} }
} }
} }
@ -132,5 +134,19 @@ namespace Grpc.Core
// TODO: use proper logging here // TODO: use proper logging here
Console.WriteLine("GRPC shutdown."); Console.WriteLine("GRPC shutdown.");
} }
private static void CheckDebugStats()
{
var remainingClientCalls = DebugStats.ActiveClientCalls.Count;
if (remainingClientCalls != 0)
{
Console.WriteLine("Warning: Detected {0} client calls that weren't disposed properly.", remainingClientCalls);
}
var remainingServerCalls = DebugStats.ActiveServerCalls.Count;
if (remainingServerCalls != 0)
{
Console.WriteLine("Warning: Detected {0} server calls that weren't disposed properly.", remainingServerCalls);
}
}
} }
} }

@ -67,6 +67,7 @@ namespace Grpc.Core.Internal
public void Initialize(Channel channel, CompletionQueueSafeHandle cq, string methodName) public void Initialize(Channel channel, CompletionQueueSafeHandle cq, string methodName)
{ {
var call = CallSafeHandle.Create(channel.Handle, cq, methodName, channel.Target, Timespec.InfFuture); var call = CallSafeHandle.Create(channel.Handle, cq, methodName, channel.Target, Timespec.InfFuture);
DebugStats.ActiveClientCalls.Increment();
InitializeInternal(call); InitializeInternal(call);
} }
@ -265,6 +266,11 @@ namespace Grpc.Core.Internal
} }
} }
protected override void OnReleaseResources()
{
DebugStats.ActiveClientCalls.Decrement();
}
/// <summary> /// <summary>
/// Handler for unary response completion. /// Handler for unary response completion.
/// </summary> /// </summary>

@ -191,6 +191,7 @@ namespace Grpc.Core.Internal
private void ReleaseResources() private void ReleaseResources()
{ {
OnReleaseResources();
if (call != null) if (call != null)
{ {
call.Dispose(); call.Dispose();
@ -199,6 +200,10 @@ namespace Grpc.Core.Internal
disposed = true; disposed = true;
} }
protected virtual void OnReleaseResources()
{
}
protected void CheckSendingAllowed() protected void CheckSendingAllowed()
{ {
Preconditions.CheckState(started); Preconditions.CheckState(started);

@ -57,6 +57,7 @@ namespace Grpc.Core.Internal
public void Initialize(CallSafeHandle call) public void Initialize(CallSafeHandle call)
{ {
DebugStats.ActiveServerCalls.Increment();
InitializeInternal(call); InitializeInternal(call);
} }
@ -112,6 +113,11 @@ namespace Grpc.Core.Internal
} }
} }
protected override void OnReleaseResources()
{
DebugStats.ActiveServerCalls.Decrement();
}
/// <summary> /// <summary>
/// Handles the server side close completion. /// Handles the server side close completion.
/// </summary> /// </summary>

@ -0,0 +1,61 @@
#region Copyright notice and license
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Threading;
namespace Grpc.Core.Internal
{
internal class AtomicCounter
{
long counter = 0;
public void Increment()
{
Interlocked.Increment(ref counter);
}
public void Decrement()
{
Interlocked.Decrement(ref counter);
}
public long Count
{
get
{
return counter;
}
}
}
}

@ -0,0 +1,45 @@
#region Copyright notice and license
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Threading;
namespace Grpc.Core.Internal
{
internal static class DebugStats
{
public static readonly AtomicCounter ActiveClientCalls = new AtomicCounter();
public static readonly AtomicCounter ActiveServerCalls = new AtomicCounter();
}
}
Loading…
Cancel
Save