Google-api-dotnet-client: Tcp Connection Leak in CLOSED_WAIT when GZIpEnabled is set on TranslateService

Created on 6 Jun 2019  路  7Comments  路  Source: googleapis/google-api-dotnet-client

When using the Google.Apis.Translate.v2 package and creating and disposing TranslateService instances we have noticed a leak of IPv4 connections.

Minimal reproduction:

using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Google.Apis.Services;
using Google.Apis.Translate.v2;

namespace Churyumov
{
    class Program
    {
        private static readonly NetworkCredential s_clientIdentity =
            new NetworkCredential(
                "<YOUR>",
                "<CREDENTIALS>");
        private static readonly string[] s_foreignText =
            new[]
            {
                "The quick brown fox jumps over the lazy dog",
                "Le renard brun rapide saute sur le chien paresseux",
                "Der schnelle braune Fuchs springt 眉ber den faulen Hund"
            };

        static async Task Main(string[] args)
        {
            var initializer = new BaseClientService.Initializer
            {
                ApplicationName = s_clientIdentity.UserName,
                ApiKey = s_clientIdentity.Password,
                GZipEnabled = true // << changing this to `false` prevents the leak 
            };

            using (var service = new TranslateService(initializer))
            {
                var request = service.Detections.List(s_foreignText);
                var response = await request.ExecuteAsync(default);
                foreach (var result in response.Detections)
                {
                    Console.WriteLine(string.Join(", ", result.Select(r => r.Language)));
                }
            }

            Console.WriteLine("Check open connections here!");
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <RootNamespace>Churyumov</RootNamespace>
    <LangVersion>Latest</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Google.Apis.Translate.v2" Version="1.40.0.875" />
  </ItemGroup>

</Project>

When inspecting the application on the Check open connections here line with lsof you can see the connection to the Google translate service has not been disposed:

$ lsof -p `pgrep dotnet` | grep IPv
dotnet  57839 willspeak   52u    IPv4 0xd178e425407bd7f9       0t0        TCP 10.11.1.61:50431->lhr48s08-in-f10.1e100.net:https (ESTABLISHED)

It looks like the TwoWayDelegatingHandler created when the GZipEnabled option is set to true doesn't properly dispose of an inner handler:

Screenshot 2019-06-05 at 17 04 12

p2 bug

All 7 comments

Thanks for reporting this.
It's meant to be disposed in TwoWayDelegatingHandler here: https://github.com/googleapis/google-api-dotnet-client/blob/6133df9980b6f65b456564a2488e538dc43a08ef/Src/Support/Google.Apis.Core/Http/TwoWayDelegatingHandler.cs#L55
I'll investigate further.

Yeah, I looked at the code in this repo and can't see why it _wouldn't_ be disposed. I don't think that Dispose(bool disposing) should be conditionally calling the base like it does: https://github.com/googleapis/google-api-dotnet-client/blob/6133df9980b6f65b456564a2488e538dc43a08ef/Src/Support/Google.Apis.Core/Http/TwoWayDelegatingHandler.cs#L51

And instead should just call base.Dispose(disposing) either before or after disposing of it's own resources. I can't see how that would stop this being disposed though as we're dealing with an explicit dispose call rather than a finalizer.

OK, the bug is here: https://github.com/googleapis/google-api-dotnet-client/blob/6133df9980b6f65b456564a2488e538dc43a08ef/Src/Support/Google.Apis.Core/Http/TwoWayDelegatingHandler.cs#L51
That call should be the base.Dispose(true), not base.Dispose().
I'll create a PR to fix it.

Ah, just seen that you'd noticed this before me :) Thanks.

This is a problem because it means the Dispose(bool) method in the base DelegatingHandler is never getting called; so the inner handler is never being disposed of.

Nice! Thanks for the quick responses. Longer term I understand we should be moving to Google.Cloud.Translation.V2 but support for this is much appreciated. Any ETA for a fixed build of this library?

The build+release process has started for v1.40.1 - it should be available on nuget.org within a couple of hours.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LindaLawton picture LindaLawton  路  9Comments

ganySA picture ganySA  路  5Comments

jamierytlewski picture jamierytlewski  路  3Comments

SonicGD picture SonicGD  路  6Comments

saadmr picture saadmr  路  5Comments