question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Make DefaultCloseTimeoutMilliseconds configurable

See original GitHub issue

I operate a chat app that involves maintaining a list of active users. When a user connects they are added to this list of active users, and when they disconnect they are removed. All clients are notified when a user is added to or removed from this list.

Here’s some simplified code showing the disconnect:

public override async Task OnDisconnectedAsync(Exception exception) {
    var currentUserId = GetCurrentUserId();
    activeUsers.RemoveAll(u => u.UserId = currentUserId);

    await Task.Delay(10000);
    if(!activeUsers.Any(u => u.UserId == currentUserId)) {
        await ChatService.MarkUserOffline(currentUserId);
        await Clients.All.SendAsync("UserOffline", currentUserId);
    }

    await base.OnDisconnectedAsync(exception);
}

It’s a bit more involved than this as the server side needs to deal with many complexities surrounding handling of online users (eg. chat requests sent to users that aren’t active when they’re caught moving between pages), but this should give you a good idea of the general gist.

You’ll note that there is a Task.Delay here. Before this delay was added, when a user refreshed the page or moved to a different page, clients would receive a UserOffline message so the user was immediately removed from the list of online users. They reappeared shortly after though when the new page was loaded and the client reconnected. To avoid this “flickering” the delay was added to only notify clients that the user left if they hadn’t reconnected after a 10 second delay. A 10 second delay should be enough to load even the slowest pages on the site and have the client reconnect whereas a delay of less than 5 seconds would in some cases be too short.

Unfortunately ASRS seems to have a problem with this delay because it throws the following exception

Microsoft.Azure.SignalR.Common.AzureSignalRException: Cancelled running application task, probably caused by time out.
  ?, in async Task ServiceConnection.ProcessIncomingMessageAsync(ClientConnectionContext connection)
  ?, in async Task ServiceConnection.ProcessClientConnectionAsync(ClientConnectionContext connection)

It looks like this occurs because ServiceConnection.cs forcibly closes the disconnect task after 5 seconds:

namespace Microsoft.Azure.SignalR
{
    internal partial class ServiceConnection : ServiceConnectionBase
    {
        private const int DefaultCloseTimeoutMilliseconds = 5000;
        ….

        private async Task ProcessIncomingMessageAsync(ClientConnectionContext connection)
        {
            // Wait for the application task to complete
            // application task can end when exception, or Context.Abort() from hub
            var app = ProcessApplicationTaskAsyncCore(connection);
 
            var cancelTask = connection.ApplicationAborted.AsTask();  // < ========= DefaultCloseTimeoutMilliseconds
            var task = await Task.WhenAny(app, cancelTask);
 
            if (task == app)
            {
                await task;
            }
            else
            {
                // cancel the application task, to end the outgoing task
                connection.Application.Input.CancelPendingRead();
                throw new AzureSignalRException("Cancelled running application task, probably caused by time out.");
            }
        }

This exception occurs each time a client disconnects, so there are a lot of exceptions being thrown.

As an aside, I’m porting this application over from SignalR for ASP.NET to SignalR for .NET Core. The ASP.NET version acts the same way, but doesn’t appear to have a problem with a 10 second timeout in the disconnect (or at least I haven’t captured any exceptions thrown as a result).

Describe the solution you’d like

I was hoping that ASRS could introduce a way to configure the DefaultCloseTimeoutMilliseconds service, so I could increase it to something like 12000ms to avoid the timeout exception.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
vicancycommented, Jul 7, 2021

Hi @ajbeaven, please try the latest package 1.9.1 which no longer cancel the application task

1reaction
ajbeavencommented, Jun 25, 2021

Either one works for me!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Timeouts WCF Services
Default for OpenTimeout is 1 minute, and default for CloseTimeout is 10 seconds. Timeouts on client side channel. There is an OperationTimeout, ...
Read more >
Configuring Timeout Values on a Binding - WCF
The following code shows how to programmatically set timeouts on a WCF binding in the ... CloseTimeout = new TimeSpan(0, 10, 0); binding....
Read more >
Timeout for in-progress requests to complete
The closetimeout parameter specifies the timeout for in-progress requests to complete in milliseconds. Set the value in the range 0 through ...
Read more >
All WCF timeouts explained - Dominik's Development Corner
All WCF timeouts explained, including Open/CloseTimeout, ... The default value is set to 0 seconds, which deactivates the timeout.
Read more >
Default timeouts in .Net code. What are they if you don't specify?
There appears to be no way to change the timeout associated with this header, and IIS appears to always timeout at 100 seconds...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found