Occasional WCF 5 seconds response spikes - c#

We are developing a client-server system where the client connects to a service and fetches an image from a buffer. The request runs at 25 hertz (25 requests per second) over a NetTcpBinding. The image data which is sent contains the image buffer (byte[]) and some meta data about the image.
What we are experiencing is that occasionally, the server does not respond for 5 seconds (5020 to 5050 ms), and we can't figure out why.
Running svc logging on the client we see the following
Activity Boundary Suspend 10:00:00:000
Activity Boundary Resume 10:00:00:003
Received a message over a channel Information 10:00:05:017
This occurs both when running the server as a managed WCF service, and an unmanaged WWS service
It can happen once every 100.000 requests, once per night, or several times per minute at seemingly random intervals.
Does anyone know what might cause this issue?

We found the solution buried in the Microsoft customer support database.
The 5 second delay is due to the firing of the SWS(Silly Window
Syndrome) avoidance timer. The SWS timer is scheduled to send the
remaining data which is less than 1 MSS (Maximum Segment Size, 1460
bytes) and the receiver is supposed to send an ACK advertising the
increased receive window and indicating that the remaining data bytes
can be sent. However, if the receiver sends an ACK when it can be
ready for sufficient buffer within 5 seconds, the SWS timer cannot
recover the 5 seconds delay status due to a race condition.
http://support.microsoft.com/kb/2020447
This issue only occurs when using localhost or 127.0.0.1. The delays do not occur when running the service and client on different machines.

Related

Exception A connection attempt failed because the connected party did not properly respond after a period of time

We get this Exception "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond" when reading from a socket (.NET Socket). This happens once in a while and we see that the sender sends an 8000+ bytes package. With the MTU of 1500, this message is split up into 6 separate messages. In Wireshark, we see that the last frame is sent with a delay of 19 - 29 seconds when the exception occurs. Normally the delay between the frames is approx 0.01 - 0.03 seconds. We are really puzzled about what could cause the last delay. We see no issues in the load of the CPU of the sender (steady at around 27%).
On this Network, there are 2 of these senders, which send these 8000+ bytes frames. And both have this issue randomly.
We expect to have a more constant delay between the messages and to receive all the frames without a timeout. We are a bit out of suggestions on what could cause this delay.

How to reduce delays caused by a Server TCP Spurious retransmission and subsequent Client TCP retransmission?

I have a Dotnet application (running on a Windows PC) which communicates with a Linux box via OPC UA. The use case here is to make ~40 read requests to the server in serial. Once these 40 read calls are complete, the next cycle of 40 read calls begins. Each read call returns a response from the server carrying a payload of ~16KB which is fragmented and delivered to the client. For most requests, the server finishes delivering the complete response within 5ms. However for some requests it takes ~300 ms to complete.
In scenarios where this delay exists, I can see the following pattern of re-transmissions.
[71612] A new Read request is sent to the server.
[71613-71630] The response is delivered to the client.
[71631] A new Read request is sent to the server.
[71632] A TCP Spurious Retransmission occurs from the server for packet [71844] with Seq No. 61624844
[71633] Client sends a DUP ACK for the packet.
[71634] Client does a TCP Retransmission for the read request in [71846] after 288ms
This delay adds up and causes some 5-6 seconds of delay for a complete cycle of 40 requests to complete. I want to figure out what is causing these retransmissions (hence delays) and what can possibly be done to-
Reduce the frequency of retransmissions.
Reduce the 300ms delay from the client side to quickly retransmit the obstructed read request.
I have tried disabling the Nagle algorithm on the server to possibly improve performance but it did not have any effect. Also, when reducing the response size by half (8KB), the retransmissions are rare and hence the delay is minute as well. But reducing the response is not a valid solution in our use case.
The connection to the Linux box is through a switch, however while directly connecting to it point-point, there is marginal reduction in the delay.
I can share relevant code but I think this issue is likely with the TCP stack (or at least, some configuration that should be enabled?) hence it would make little difference.

xamarin bluetooth data receive delay

I have my xamarin app running on android. It connects to a custom device through bluetooth using SPP. The App issues commands and the device responds with about 260 bytes.
My problem is that there appears to be a large delay between data being sent by the device and that data being available to my app through the socket. This results in the throughput of the connection being very low.
Scope image here: https://imgur.com/a/gBPaWHJ
In the image, the yellow trace is the data being sent to the device, the blue is the response. As you can see, the device responds immediately after the command is sent. I have measured the peroid from the start of a command to the end of the response to be 12ms.
In the code, I measured the time between the app receiving the last byte of a response to the the sending of the next command. The time was always 0 or 1ms. This is not what the scope is telling me, there is a clear 92ms period between the end of a response and the sending of the next command.
I also measured the time between the line of code that sends data, and the first byte of the response being received, it always takes 50 to 80ms. This here is the problem.
I have been through my code and there are no delays or timers that prevent a command being sent. If it has received a full resonse, it will send a request for data straight away.
I have a System.Threading.Thread which loops around handling the sending and receiving of data. I have timed this loop and it always takes less than 3ms to complete (mostly it is 0ms). This shows there is no delay in my loop causing this. I wouldnt expect any delay as we're only talking about 260 bytes of data to read and process.
Is there something in Xamarin Android that might cause a delay between data arriving at the tablet over bluetooth and data being available to my app. Perhaps something is only updating the BluetoothSocket every 100ms? I want those empty gaps on my scope to be gone.
In general, the factors that affect Bluetooth transmission are as follows: Connection Interval / number of frames sent per Connection Event / length of each frame of data, and an operation type (not considered at this time).
According to the optimal value supported by the Android protocol, you can set the Connection Interval to 7.5ms, and the data size of each frame is 20 bytes.
If you need to send 260 bytes of data, then the time required for the calculation is 97.5ms. Sometimes it may involve fluctuations in the stability of the Bluetooth connection, which takes about 100ms.
why is it limited to 20 bytes?
The core spec defines the default MTU of the ATT to be 23 bytes. After removing one byte of the ATT opcode and the ATT handle2 bytes, the remaining 20 bytes are reserved for the GATT.
Considering that some Bluetooth smart devices are weak and don't dare to use memory space too much, the core spec requires that each device must support an MTU of 23.
At the beginning of the connection between the two devices, everyone is like a new friend, I don't know the other party's fine, so strictly follow the routine, that is, send up to 20 bytes at a time, which is the most insurance.
How to break through 20?
Since the maximum length of the ATT is 512 bytes, it is sufficient to change the MTU of the transmitted ATT. On Android (API 21), the interface for changing the ATT MTU is:
public boolean requestMtu (int mtu)
#Added in API level 21
#Request an MTU size used for a given connection.
#When performing a write request operation (write without response), the data sent is truncated to the MTU size. This function may be used to request a larger MTU size to be able to send more data at once.
#A onMtuChanged(BluetoothGatt, int, int) callback will indicate whether this operation was successful.
#Requires BLUETOOTH permission.
#Returns true, if the new MTU value has been requested successfully
If your peripheral application changes the MTU and succeeds, then this callback will also be called.
#Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
this.supportedMTU = mtu;//local var to record MTU size
}
}
After that, you can happily send the length of the supportedMTU data.
So this is actually not related to xamarin, this is just a limitation imposed by Android.

Rabbitmq server drops connection when client takes more than 60 seconds to acknowledge a message

I am currently using EventingBasicConsumer from RabbitMQClient.dll C# client, we spawn a different thread to handle each message that is delivered to the consumer.
We encountered a strange behavior, the RabbitMQ server closes connections at
times with the error missed heartbeats from client, timeout: 60s. Few moments later the client reports an error saying Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Library, code=541. I also see this error client unexpectedly closed TCP connection happening more frequently.
In some situations the clients may take more than 60 seconds to process one job request and this error happens under such conditions.
Is it required that a job be processed within 60 seconds ?, because for our process this can vary between 30 seconds to 5 minutes.
RabbitMQ server: 3.6.6
RabbitMQ.Client.dll (C# client): RabbitMQ.Client.4.1.1
Any insight into this issue is greatly appreciated.
I used to run much longer jobs (minutes) with EasyNetQ. It's more high-level client that wraps RabbitMQ.Client.
For me, the reason of these errors is something like Evk wrote in this comment. I would try EasyNetQ as it likely has fetching of messages decoupled from the handling process.
You can increase the TTL timeout in RabbitMq both per queue and per message
IBasicProperties mqProps = model.CreateBasicProperties();
mqProps.ContentType = "text/plain";
mqProps.DeliveryMode = 2;
mqProps.Expiration = "300000"
model.BasicPublish(exchangeName,
routingKey, mqProps,
messageBodyBytes);
Documentaion is at
https://www.rabbitmq.com/ttl.html
But I think you're better off by rewriting it to Async pattern for the actual processing of the message.
This might give you inspiration for doing async message processing with RabbitMq
https://codereview.stackexchange.com/questions/42836/listen-to-multiple-rabbitmq-queue-by-task-and-process-the-message
And in this question there are quite allot of information too on async message consumption.
multi-threading based RabbitMQ consumer

Application throwing time out exception on sending bulk data

I have a Console Application which consumes a BizTalk Web Service. The Problem is that when I send the BizTalk Service object data in bulk, my console application throws the exception:
Application has either timed out or is Timing out.
My application actually needs to wait for the Biztalk service to finish processing its job. Increasing the obj.Timeout value was of no help. Is there anything else other than using Thread.Sleep method (which I want to avoid)?
Below is the relevant code snippet from my application:
pumpSyncService.Timeout = 750000;
outputRecords = pumpSyncService.PumpSynchronization(pumpRecords);
The pump records contain an array of objects. When the count is around 30, I get a correct response, but when the count increases to around 150 I get the exception.
Try sending smaller chunks in a loop. Instead of sending 150 all at once, send 30 records 5 times. The timeout might be happening because it takes too long to send 150 records.
you should be able to send all 30 at once , if the service allows you to. I am assuming you have verified that the event kicking this off is not firing 5 times . try it asynchronously and process your results when they come back.

Categories