Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unknown disconnect happened and "ThrowInvalidOperationException_BackpressureDeadlock" #10701

Closed
hours10000 opened this issue May 31, 2019 · 16 comments
Labels
area-signalr Includes: SignalR clients and servers investigate
Milestone

Comments

@hours10000
Copy link

hours10000 commented May 31, 2019

coordserver.log

Describe the bug

When I send several small message from signalr client to signalr hub,sometimes will raise a disconnect event. Message package is very small: 40B more or less , one per millisecond . The hub side do some time-consuming operations, 2 second in one message process operation。

When disconnect happened, the exception is null:2019-05-31 22:06:36,494 [6] DEBUG (null) CoordServer.Hubs.ServerHub >>> OnDisconnectedAsync Start, exception: (null)

or :2019-05-31 22:13:40,699 [23] ERROR (null) Microsoft.AspNetCore.SignalR.HubConnectionHandler >>> Error when processing requests. System.InvalidOperationException: Advancing examined to the end would cause pipe to deadlock because FlushAsync is waiting. at System.IO.Pipelines.ThrowHelper.ThrowInvalidOperationException_BackpressureDeadlock() at System.IO.Pipelines.Pipe.AdvanceReader(BufferSegment consumedSegment, Int32 consumedIndex, BufferSegment examinedSegment, Int32 examinedIndex) at System.IO.Pipelines.Pipe.AdvanceReader(SequencePosition& consumed, SequencePosition& examined) at System.IO.Pipelines.Pipe.DefaultPipeReader.AdvanceTo(SequencePosition consumed, SequencePosition examined) at Microsoft.AspNetCore.SignalR.HubConnectionHandler1.DispatchMessagesAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler1.RunHubAsync(HubConnectionContext connection).

From these links , I thought it maybe something about the size of ApplicationMaxBufferSize ,
but

Today SignalR needs to buffer the entire message before it calls your hub and it doesn't start consuming the buffer until it seems an entire message.

In my program, the message size is so small, why I still met this error?
Any helps? Thanks!

2266
8142
2322
5307

Additional context

Microsoft.AspNetCore.SignalR.Client 1.1.0
Microsoft.NETCore.App 2.2.0

@Eilon Eilon added the area-signalr Includes: SignalR clients and servers label May 31, 2019
@hours10000
Copy link
Author

hours10000 commented Jun 3, 2019

ChatSample.zip

Hi,
I tried with the sample in SignalR-samples,It's has the same problem。
I just add two function in this sample:

public async Task MessageBoxGetList(string resKey, W2CMsgGetListReq req) { _logger.LogInformation("MessageBoxGetList: {0}", req.account); System.Threading.Thread.Sleep(2 * 1000); }

public override Task OnDisconnectedAsync(Exception exception) { _logger.LogInformation("OnDisconnectedAsync: {0}", exception); return base.OnDisconnectedAsync(exception); }

Thanks.

ChatSample.txt

@hours10000
Copy link
Author

hours10000 commented Jun 3, 2019

Hi,
I checked the source code, the disconnect:
2019-05-31 22:06:36,494 [6] DEBUG (null) CoordServer.Hubs.ServerHub >>> OnDisconnectedAsync Start, exception: (null)
comes from RunHubAsync function(in the red part of runasync.png ),
Why the exception is null ?Maybe because the result.IsCanceled or result.IsCompleted (in the red part of dispatchMessageAsync.png).
But , my client is sending messages all the time when the server met the disconnect event.

Thanks.

runasync
dispatchMessageAsync

@davidfowl
Copy link
Member

How big are the messages you are sending?

@hours10000
Copy link
Author

Thanks for your response。

How big are the messages you are sending?

About 40B, every messsage just contains a string ,like this "test:index:9-timestramp:1559313957345" .

@hours10000
Copy link
Author

hours10000 commented Jun 3, 2019

This is the definition of the message:

public interface IApiMessage { }

public class W2CMsgGetListReq : IApiMessage
{
    public string account;
}

@analogrelay analogrelay added this to the 3.0.0-preview7 milestone Jun 4, 2019
@hours10000
Copy link
Author

hours10000 commented Jun 6, 2019

Hi , I know, the reason of the first disconnect exception:
When I modified the log level from info ->debug, I got this :
Client timeout (30021ms) elapsed without receiving a message from the client. Closing connection.
Then, I will get this exception:
DEBUG (null) CoordServer.Hubs.ServerHub >>> OnDisconnectedAsync Start, exception: (null)

This is because the Hub function "MessageBoxGetList" is a time-consuming function, the DefaultClientTimeoutInterval is 30 seconds, So If my Hub got 16 message (every message cost 2s) in one time , this exception will appear.

@hours10000
Copy link
Author

But I still did not find out the reason why this happened:

2019-06-06 19:39:34,256 [6] ERROR (null) Microsoft.AspNetCore.SignalR.HubConnectionHandler >>> Error when processing requests. System.InvalidOperationException: Advancing examined to the end would cause pipe to deadlock because FlushAsync is waiting. at System.IO.Pipelines.ThrowHelper.ThrowInvalidOperationException_BackpressureDeadlock() at System.IO.Pipelines.Pipe.AdvanceReader(BufferSegment consumedSegment, Int32 consumedIndex, BufferSegment examinedSegment, Int32 examinedIndex) at System.IO.Pipelines.Pipe.AdvanceReader(SequencePosition& consumed, SequencePosition& examined) at System.IO.Pipelines.Pipe.DefaultPipeReader.AdvanceTo(SequencePosition consumed, SequencePosition examined) at Microsoft.AspNetCore.SignalR.HubConnectionHandler1.DispatchMessagesAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler1.RunHubAsync(HubConnectionContext connection)

I really did not send a huge message, and every message I send to Hub just in 40B more or less.

@BrennanConroy
Copy link
Member

Took a look at this and your analysis is correct

This is because the Hub function "MessageBoxGetList" is a time-consuming function, the DefaultClientTimeoutInterval is 30 seconds, So If my Hub got 16 message (every message cost 2s) in one time , this exception will appear.

The team will discuss this and decide on whether we can do anything here.

On a side-note, it's probably not a good idea to have your client send a message every millisecond if it takes the server 2 seconds to process the message.

@BrennanConroy BrennanConroy added the triage-focus Add this label to flag the issue for focus at triage label Jun 10, 2019
@analogrelay
Copy link
Contributor

Based on the investigation I don't think we have a clear idea on how to prevent this kind of overload in 3.0. Moving to the backlog.

On a side-note, it's probably not a good idea to have your client send a message every millisecond if it takes the server 2 seconds to process the message.

@hours10000 This really is the source of the problem. If you take 2 seconds to process a message but messages are arriving consistently faster than that, you're creating an ever-growing queue. The ping timeout is a symptom of this, but I think you need some kind of batching on the client side to avoid overloading the server like this. As I said above, we do think we could do better at protecting you from this, but it's still a bit of a design problem to be sending messages much faster than you can process them.

@analogrelay analogrelay modified the milestones: 3.0.0-preview7, Backlog Jun 11, 2019
@analogrelay analogrelay removed triage-focus Add this label to flag the issue for focus at triage labels Jun 11, 2019
@davidfowl
Copy link
Member

In 3.0 the error won't happen, you'll just get throttled.

@hours10000
Copy link
Author

hours10000 commented Jun 12, 2019

Thanks for all your response about this disconnect event "OnDisconnectedAsync Start, exception: (null)"。
Yes, I have done something on my client to avoid overloading the server like this 。

@hours10000
Copy link
Author

hours10000 commented Jun 12, 2019

In 3.0 the error won't happen, you'll just get throttled.

Hi, @davidfowl
Allow me to confirm: Is your answer to this error : "Error when processing requests. System.InvalidOperationException: Advancing examined to the end would cause pipe to deadlock because FlushAsync is waiting" ?Thanks.

@davidfowl
Copy link
Member

Allow me to confirm: Is your answer to this error : "Error when processing requests. System.InvalidOperationException: Advancing examined to the end would cause pipe to deadlock because FlushAsync is waiting" ?Thanks.

Yes, this exception has been removed completely from 3.0.

@halter73
Copy link
Member

I will add that in 3.0, you will only get throttled if you don't advance the "examined" position. If you "examine" untrusted data that arrives without bounds (maybe you're scanning for a separator token before parsing a message for example), you've just opened yourself up to a big memory leak.

@davidfowl
Copy link
Member

That’s not exposed to SignalR users. We also have a max message limit in SignalR itself

@analogrelay
Copy link
Contributor

We no longer throw this error in 3.0. There is still a maximum message size, but it is configurable (and docs will be updated).

@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-signalr Includes: SignalR clients and servers investigate
Projects
None yet
Development

No branches or pull requests

6 participants