Note that there are some explanatory texts on larger screens.

plurals
  1. POSignalR seems to be slowing startup of my MVC / Azure application
    primarykey
    data
    text
    <p>I have an MVC application running under .NET 4.5 on a WebRole on Windows Azure, employing SignalR 1.0 -alpha2, and using the ServiceBus backplane. In my App_Start folder I have RegisterHubs.cs, as follows:</p> <pre><code>[assembly: PreApplicationStartMethod(typeof(pageengine.studio.RegisterHubs), "Start")] namespace pageengine.studio { public static class RegisterHubs { public static void Start() { // Register the default hubs route: ~/signalr/hubs RouteTable.Routes.MapHubs(); } } } </code></pre> <p>And in Global.asax, I have the following:</p> <pre><code>protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); String connectionString = "Endpoint=sb://MYNAMESPACE.servicebus.windows.net/;SharedSecretIssuer=MY_ISSUER;SharedSecretValue=MY_SECRET_VALUE"; GlobalHost.DependencyResolver.UseWindowsAzureServiceBus(connectionString, 1); } </code></pre> <p>I've run tests as above (call this MVC + SignalR + ServiceBus), with the <code>GlobalHost.DependencyResolver ...</code> line in Global.asax commented out (MVC + SignalR), and with both lines <code>[assembly: PreApplicationStartMethod ...</code> and <code>RouteTable.Routes.MapHubs();</code> also commented out (MVC Alone). </p> <p>Before beginning, I fire up the Azure emulator using Start Without Debugging (and deploying to IIS Express), and after each commenting / uncommenting, I rebuild the application, then do a hard reload in Google Chrome. My average load times over ten tests are as follows:</p> <blockquote> <p>MVC Alone: 1.33 seconds</p> <p>MVC + SignalR: 31.95 seconds</p> <p>MVC + SignalR + ServiceBus: 53.1 seconds</p> </blockquote> <p>I have not run the same comparison on my live Azure site, but the reason for running these tests is that after implementing SignalR, it is running noticeably slower.</p> <p>I had assumed this was just due to SignalR being in alpha, but discussion elsewhere (<a href="https://stackoverflow.com/questions/13579598/signalr-mvc-site-loads-indefinitely-after-signalr-install">signalR MVC site loads indefinitely after signalR install</a>) suggests this shouldn't be so. I'm not sure if there is something wrong with my implementation above, or if this is an Azure-specific issue, or something else.</p> <p>Is anybody else experiencing similar performance issues? Is there anything wrong with my code above? Does anyone have any potential remedies?</p> <p><strong>Update</strong></p> <p>I've added a trace statement to the WebRole Start and Run methods, to the beginning and end of the <code>RegisterHubs</code> method, and to the beginning and end of the <code>Application_Start</code> method, and commented out the ServiceBus code so I'm just testing MVC + SignalR. </p> <p>Again, over a number of tests, the results are consistent:</p> <blockquote> <p>Web Role OnStart: 20:55:17</p> <p>Web Role Run: 20:55:17</p> <p>RegisterHubs Start In: 20:55:28</p> <p>RegisterHubs Start Out: 20:56:10 // 42 seconds. Average was nearer 45.</p> <p>Application_Start In: 20:56:14</p> <p>Application_Start Out: 20:56:21</p> </blockquote> <p>For reference, my RegisterHubs method now looks like this:</p> <pre><code>public static void Start() { System.Diagnostics.Debug.WriteLine("RegisterHubs Start In: " + DateTime.Now.ToLongTimeString()); // Register the default hubs route: ~/signalr/hubs RouteTable.Routes.MapHubs(); System.Diagnostics.Debug.WriteLine("RegisterHubs Start Out: " + DateTime.Now.ToLongTimeString()); } </code></pre> <p><strong>Further Update</strong></p> <p>The issue is (ironically enough) in the <code>PerformaceCounterManager</code> class, in the <code>Microsoft.AspNet.SignalR.Core</code> assembly. </p> <p>The function <code>SetCounterProperties()</code> calls <code>LoadCounter</code> over a loop of 23 different <code>_counterProperties</code>. Each of these calls fails and the exception is handled, resulting in a return of <code>_noOpCounter</code>, but the fail is taking between one and two seconds to occur, and this accumulates to a forty second lag (all these timings with the debugger on - it's quicker without, of course, but still perceptibly laggy). </p> <p>Here's a trace of the handled exception, in case that's useful:</p> <p><code>A first chance exception of type 'System.InvalidOperationException' occurred in System.dll InvalidOperation: SignalR - Errors: Hub Invocation Total - deployment18(966).Azure.Studio_IN_0_Web - System.InvalidOperationException: Cannot load Counter Name data because an invalid index '' was read from the registry. at System.Diagnostics.PerformanceCounterLib.GetStringTable(Boolean isHelp) at System.Diagnostics.PerformanceCounterLib.get_NameTable() at System.Diagnostics.PerformanceCounterLib.get_CategoryTable() at System.Diagnostics.PerformanceCounterLib.CategoryExists(String category) at System.Diagnostics.PerformanceCounterLib.CategoryExists(String machine, String category) at System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName, String machineName) at System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName) at Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.LoadCounter(String categoryName, String counterName, String instanceName) in d:\Work\CLIENTS\PageEngine\Resources\SignalR-master\src\Microsoft.AspNet.SignalR.Core\Infrastructure\PerformanceCounterManager.cs:line 275</code></p> <p>Easiest workaround I could find was to have no PerformanceCounters. <strike>For the time being I've modified <code>GetPropertyInfo()</code> to return simply <code>new PropertyInfo[0]</code>.</strike> I've modified <code>LoadCounter</code> to always return <code>_noOpCounter</code>. Startup time is now about 5 seconds, or 10 with the Service Bus. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload