Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-2645

SocketException: An operation on a socket could not be performed

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.8.1
    • Component/s: None
    • Labels:
      None
    • Environment:
      Azure Win 10 (App services) - S1 1.75 GB
      .Net Core 2.2

      Hi guys.

      I'm running a stress test with JMeter and I'm facing the following error:

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      // Error
      SocketException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full
      
      System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, string callerName)System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)System.Net.Sockets.Socket.InternalBind(EndPoint localEP)System.Net.Sockets.Socket.BeginConnectEx(EndPoint remoteEP, bool flowContext, AsyncCallback callback, object state)System.Net.Sockets.Socket.UnsafeBeginConnect(EndPoint remoteEP, AsyncCallback callback, object state, bool flowContext)System.Net.Sockets.Socket.BeginConnect(EndPoint remoteEP, AsyncCallback callback, object state)System.Net.Sockets.Socket.ConnectAsync(EndPoint remoteEP)MongoDB.Driver.Core.Connections.TcpStreamFactory.ConnectAsync(Socket socket, EndPoint endPoint, CancellationToken cancellationToken)MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken)MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)
      
      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
       MongoConnectionException: An exception occurred while opening a connection to the server.
      
      MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)
      MongoDB.Driver.Core.Servers.Server.GetChannelAsync(CancellationToken cancellationToken)
      MongoDB.Driver.Core.Operations.FindOperation<TDocument>.ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
      MongoDB.Driver.OperationExecutor.ExecuteReadOperationAsync<TResult>(IReadBinding binding, IReadOperation<TResult> operation, CancellationToken cancellationToken)
      MongoDB.Driver.MongoCollectionImpl<TDocument>.ExecuteReadOperationAsync<TResult>(IClientSessionHandle session, IReadOperation<TResult> operation, ReadPreference readPreference, CancellationToken cancellationToken)
      MongoDB.Driver.MongoCollectionImpl<TDocument>.UsingImplicitSessionAsync<TResult>(Func<IClientSessionHandle, Task<TResult>> funcAsync, CancellationToken cancellationToken)
      MongoDB.Driver.IAsyncCursorSourceExtensions.FirstOrDefaultAsync<TDocument>(IAsyncCursorSource<TDocument> source, CancellationToken cancellationToken)
      

      JMeter setup is:

      100 threads in parallel
      20x in loop (the next round starts after previews one has finished)

      The error occurs around the 8th round.

      It seems Windows is running out of ports to handle requests, but my question is: shouldn't sockets be reused?

      In my head I thought that since the maximum parallel requests count is 100, it should use 100 ports only.

       

      My Mongo client config (it's called once per application lifetime):

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      // code placeholder
      var settings = MongoClientSettings.FromConnectionString(config.CacheConnection);void SocketConfigurator(Socket s) => s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);            settings.SocketTimeout = TimeSpan.FromMinutes(5);
      settings.ConnectTimeout = TimeSpan.FromSeconds(60);
      settings.MaxConnectionIdleTime = TimeSpan.FromSeconds(30);
      settings.ClusterConfigurator = cb => cb.ConfigureTcp(tcp => tcp.With(socketConfigurator: (Action<Socket>)SocketConfigurator));            var mongoClient = new MongoClient(settings);            services.AddScoped<ICacheDatabase>(t => new CacheDatabase(config, mongoClient));
      

      My socket config:

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      internal struct KeepAliveValues
              {
                  public uint OnOff { get; set; }
                  public uint KeepAliveTime { get; set; }
                  public uint KeepAliveInterval { get; set; }
      
                  public byte[] ToBytes()
                  {
                      var bytes = new byte[12];
                      Array.Copy(BitConverter.GetBytes(OnOff), 0, bytes, 0, 4);
                      Array.Copy(BitConverter.GetBytes(KeepAliveTime), 0, bytes, 4, 4);
                      Array.Copy(BitConverter.GetBytes(KeepAliveInterval), 0, bytes, 8, 4);
                      return bytes;
                  }
              }
      
              internal static void SocketConfigurator(Socket s)
              {
                  var keepAliveValues = new KeepAliveValues()
                  {
                      OnOff = 1,
                      KeepAliveTime = 120 * 1000,   // 120 seconds in milliseconds
                      KeepAliveInterval = 10 * 1000 // 10 seconds in milliseconds
                  };
      
                  s.IOControl(IOControlCode.KeepAliveValues, keepAliveValues.ToBytes(), null);
              }
      

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            austinfelipe Austin Felipe
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: