Skip to content

Commit

Permalink
Added test to verify reconnect fires after host shutdown with LP
Browse files Browse the repository at this point in the history
  • Loading branch information
halter73 committed Jul 23, 2013
1 parent 37b037b commit 33ab1a8
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 9 deletions.
15 changes: 8 additions & 7 deletions src/Microsoft.AspNet.SignalR.Hosting.Memory/MemoryHost.cs
Expand Up @@ -26,6 +26,7 @@ public class MemoryHost : IHttpClient, IDisposable
private readonly CancellationTokenSource _shutDownTokenSource = new CancellationTokenSource();
private readonly CancellationToken _shutDownToken;
private int _disposed;
private IAppBuilder _appBuilder;
private AppFunc _appFunc;
private string _instanceName;
private readonly Lazy<string> _defaultInstanceName;
Expand All @@ -47,15 +48,15 @@ public void Configure(Action<IAppBuilder> startup)
throw new ArgumentNullException("startup");
}

var builder = new AppBuilder();
_appBuilder = new AppBuilder();

builder.Properties[OwinConstants.ServerCapabilities] = new Dictionary<string, object>();
builder.Properties[OwinConstants.HostOnAppDisposing] = _shutDownToken;
builder.Properties[OwinConstants.HostAppNameKey] = InstanceName;
_appBuilder.Properties[OwinConstants.ServerCapabilities] = new Dictionary<string, object>();
_appBuilder.Properties[OwinConstants.HostOnAppDisposing] = _shutDownToken;
_appBuilder.Properties[OwinConstants.HostAppNameKey] = InstanceName;

startup(builder);
startup(_appBuilder);

_appFunc = Build(builder);
_appFunc = Build(_appBuilder);
}

public string InstanceName
Expand Down Expand Up @@ -123,7 +124,7 @@ private Task<IClientResponse> ProcessRequest(string httpMethod, string url, Acti
// REVIEW: Should we add a new method to the IClientResponse to trip this?
var clientTokenSource = new SafeCancellationTokenSource();

var env = new OwinEnvironment();
var env = new OwinEnvironment(_appBuilder.Properties);

// Request specific setup
var uri = new Uri(url);
Expand Down
17 changes: 15 additions & 2 deletions src/Microsoft.AspNet.SignalR.Hosting.Memory/OwinEnvironment.cs
Expand Up @@ -10,6 +10,7 @@ namespace Microsoft.AspNet.SignalR.Hosting.Memory
internal class OwinEnvironment : IDictionary<string, object>
{
private IDictionary<string, object> _extraProperties;
private IDictionary<string, object> _hostProperties;

private string _requestProtocol;
private CancellationToken _callCancelled;
Expand Down Expand Up @@ -42,6 +43,11 @@ internal class OwinEnvironment : IDictionary<string, object>
OwinConstants.ResponseBody,
};

public OwinEnvironment(IDictionary<string, object> hostProperties)
{
_hostProperties = hostProperties;
}

private IDictionary<string, object> ExtraProperties
{
get
Expand Down Expand Up @@ -69,7 +75,7 @@ public ICollection<string> Keys
{
return _defaultKeys;
}
return _defaultKeys.Concat(_extraProperties.Keys).ToArray();
return _defaultKeys.Concat(_extraProperties.Keys).Concat(_hostProperties.Keys).ToArray();
}
}

Expand Down Expand Up @@ -125,7 +131,14 @@ public bool TryGetValue(string key, out object value)
value = _responseBody;
return true;
default:
return ExtraProperties.TryGetValue(key, out value);
if (ExtraProperties.TryGetValue(key, out value))
{
return true;
}
else
{
return _hostProperties.TryGetValue(key, out value);
}
}
}

Expand Down
Expand Up @@ -88,6 +88,7 @@
<Compile Include="Server\Connections\DisconnectFacts.cs" />
<Compile Include="Server\Connections\NameValueCollectionWrapper.cs" />
<Compile Include="Server\Connections\PersistentConnectionFacts.cs" />
<Compile Include="Server\Connections\ReconnectFacts.cs" />
<Compile Include="Server\Hubs\HubAuthFacts.cs" />
<Compile Include="Server\Hubs\HubFacts.cs" />
<Compile Include="Server\Hubs\SecurityFacts.cs" />
Expand Down
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Tests.Common.Infrastructure;
using System.Diagnostics;
using Owin;
using Microsoft.AspNet.SignalR.Hosting.Memory;
using Xunit.Extensions;
using Xunit;
using System.Threading;
using Microsoft.AspNet.SignalR.Tests.Common;

namespace Microsoft.AspNet.SignalR.Tests
{
public class ReconnectFacts : HostedTest
{
[Theory]
[InlineData(TransportType.LongPolling, MessageBusType.Default)]
[InlineData(TransportType.LongPolling, MessageBusType.Fake)]
[InlineData(TransportType.LongPolling, MessageBusType.FakeMultiStream)]
public void ReconnectFiresAfterHostShutdown(TransportType transportType, MessageBusType messageBusType)
{
MyReconnect conn = null;
var host = new ServerRestarter(app =>
{
var config = new ConnectionConfiguration
{
Resolver = new DefaultDependencyResolver()
};
UseMessageBus(messageBusType, config.Resolver);
app.MapConnection<MyReconnect>("/endpoint", config);
conn = new MyReconnect();
config.Resolver.Register(typeof(MyReconnect), () => conn);
});

using (host)
{
var connection = new Client.Connection("http://foo/endpoint");
var transport = CreateTransport(transportType, host);
connection.Start(transport).Wait();

Thread.Sleep(TimeSpan.FromSeconds(2));
host.Restart();

connection.Stop();

Assert.Equal(1, conn.Reconnects);
}
}

private class ServerRestarter : Client.Http.IHttpClient, IDisposable
{
private readonly Action<IAppBuilder> _startup;
private MemoryHost _server;
private int _counter = 0;
private readonly object _lockobj = new object();

public void Initialize(SignalR.Client.IConnection connection)
{
// Not implemented by MemoryHost
}

public ServerRestarter(Action<IAppBuilder> startup)
{
_startup = startup;
Restart();
}

public Task<Client.Http.IResponse> Get(string url, Action<Client.Http.IRequest> prepareRequest, bool isLongRunning)
{
lock (_lockobj)
{
Debug.WriteLine("Server {0}: GET {1}", _counter, url);
return ((Client.Http.IHttpClient)_server).Get(url, prepareRequest, isLongRunning);
}
}

public Task<Client.Http.IResponse> Post(string url, Action<Client.Http.IRequest> prepareRequest, IDictionary<string, string> postData, bool isLongRunning)
{
lock (_lockobj)
{
Debug.WriteLine("Server {0}: POST {1}", _counter, url);
return ((Client.Http.IHttpClient)_server).Post(url, prepareRequest, postData, isLongRunning);
}
}

public void Restart()
{
lock (_lockobj)
{
Dispose();
_server = new MemoryHost();
// Ensure that all servers have the same instance name so tokens can be successfully unprotected
_server.InstanceName = "ServerRestarter";
_server.Configure(_startup);
_counter++;
}
}

public void Dispose()
{
lock (_lockobj)
{
if (_server != null)
{
_server.Dispose();
}
}
}
}
}
}

0 comments on commit 33ab1a8

Please sign in to comment.