Repository: localstack/localstack

Issue:
bug: [SQS] LocalStack in ASF mode doesn't process multiple messages sent concurrently
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

When multiple (hundreds of) messages are attempted to be sent concurrently, LS 1.0.4 (in default ASF mode) is unable to receive them.
In legacy mode (LEGACY_EDGE_PROXY=1) all messages are received successfully.

### Expected Behavior

LS in ASF mode should be able to receive (process) multiply messages sent concurrently.

### How are you starting LocalStack?

With a `docker run` command

### Steps To Reproduce

#### How are you starting localstack (e.g., `bin/localstack` command, arguments, or `docker-compose.yml`)

docker run -p 4566:4566 --rm -e SERVICES=sqs -e EAGER_SERVICE_LOADING=1 localstack/localstack:1.0.4

#### Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)
The issue is reproducible with this AWS SDK code snippet:

```
static async Task TestSQS()
{
    const int numMsgs = 500;
	
    Stopwatch stopWatch = new Stopwatch();
    using (AmazonSQSClient SQS = new AmazonSQSClient("ignore", "ignore", new AmazonSQSConfig { ServiceURL = "http://localhost:4566" }))
    {
        CreateQueueResponse createQueueResp = await SQS.CreateQueueAsync($"testQueue_{Guid.NewGuid()}");

        // Send messages
        Console.WriteLine($"Sending {numMsgs} messages...");
        string msgText = new string('x', 100);
        Task[] sentMsgs = new Task[numMsgs];
        stopWatch.Start();
        for (int i = 0; i < numMsgs; i++)
        {
            sentMsgs[i] = SQS.SendMessageAsync(createQueueResp.QueueUrl, msgText);
        }
        await Task.WhenAll(sentMsgs);
        stopWatch.Stop();
        Console.WriteLine($"Num. messages = {numMsgs,2}  Sending time = {stopWatch.ElapsedMilliseconds} ms");

        await SQS.DeleteQueueAsync(createQueueResp.QueueUrl);
    }
}
```
After couple of minutes the application fails with this exception:
```
Sending 500 messages...
Unhandled exception. System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at Amazon.Runtime.HttpWebRequestMessage.GetResponseAsync(CancellationToken cancellationToken)
   at Amazon.Runtime.Internal.HttpHandler`1.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Unmarshaller.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.SQS.Internal.ValidationResponseHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
   ...
```

In legacy mode (LEGACY_EDGE_PROXY=1) sending is successful and the output looks like this:
```
Sending 500 messages...
Num. messages = 500  Sending time = 4410 ms
```


### Environment

```markdown
- OS: Win 10 (1909)
- LocalStack: 1.0.4
- AWSSDK.SQS 3.7.2.94 / .NET Core 3.1
```


### Anything else?

_No response_


Discussion:

Resolving patch:
diff --git a/localstack/aws/serving/asgi.py b/localstack/aws/serving/asgi.py
--- a/localstack/aws/serving/asgi.py
+++ b/localstack/aws/serving/asgi.py
@@ -15,7 +15,7 @@ class AsgiGateway:
     gateway: Gateway
 
     def __init__(
-        self, gateway: Gateway, event_loop: Optional[AbstractEventLoop] = None, threads: int = 100
+        self, gateway: Gateway, event_loop: Optional[AbstractEventLoop] = None, threads: int = 1000
     ) -> None:
         self.gateway = gateway
 


Test patch: