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

SocketException: An operation on a socket could not be performed

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major - P3 Major - P3
    • None
    • 2.8.1
    • None
    • None
    • Azure Win 10 (App services) - S1 1.75 GB
      .Net Core 2.2

    Description

      Hi guys.

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

      // 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)
      

       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):

      // 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:

      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);
              }
      

      Attachments

        Activity

          People

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

            Dates

              Created:
              Updated:
              Resolved: