Add ServiceContext to make it easier to flow new services through ctors

This commit is contained in:
Stephen Halter 2015-09-03 12:42:28 -07:00
parent 1584d70e1f
commit f10c989d90
13 changed files with 53 additions and 28 deletions

View File

@ -13,9 +13,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public abstract class Listener : ListenerContext, IDisposable public abstract class Listener : ListenerContext, IDisposable
{ {
protected Listener(IMemoryPool memory) protected Listener(ServiceContext serviceContext) : base(serviceContext)
{ {
Memory = memory;
} }
protected UvStreamHandle ListenSocket { get; private set; } protected UvStreamHandle ListenSocket { get; private set; }

View File

@ -10,11 +10,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
public ListenerContext() { } public ListenerContext() { }
public ListenerContext(ListenerContext context) public ListenerContext(ServiceContext serviceContext)
{ {
Thread = context.Thread; Memory = serviceContext.Memory;
Application = context.Application; }
Memory = context.Memory;
public ListenerContext(ListenerContext listenerContext)
{
Thread = listenerContext.Thread;
Application = listenerContext.Application;
Memory = listenerContext.Memory;
} }
public KestrelThread Thread { get; set; } public KestrelThread Thread { get; set; }

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
// but it has no other functional significance // but it has no other functional significance
private readonly ArraySegment<ArraySegment<byte>> _dummyMessage = new ArraySegment<ArraySegment<byte>>(new[] { new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }) }); private readonly ArraySegment<ArraySegment<byte>> _dummyMessage = new ArraySegment<ArraySegment<byte>>(new[] { new ArraySegment<byte>(new byte[] { 1, 2, 3, 4 }) });
protected ListenerPrimary(IMemoryPool memory) : base(memory) protected ListenerPrimary(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -15,9 +15,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public abstract class ListenerSecondary : ListenerContext, IDisposable public abstract class ListenerSecondary : ListenerContext, IDisposable
{ {
protected ListenerSecondary(IMemoryPool memory) protected ListenerSecondary(ServiceContext serviceContext) : base(serviceContext)
{ {
Memory = memory;
} }
UvPipeHandle DispatchPipe { get; set; } UvPipeHandle DispatchPipe { get; set; }

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public class PipeListener : Listener public class PipeListener : Listener
{ {
public PipeListener(IMemoryPool memory) : base(memory) public PipeListener(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public class PipeListenerPrimary : ListenerPrimary public class PipeListenerPrimary : ListenerPrimary
{ {
public PipeListenerPrimary(IMemoryPool memory) : base(memory) public PipeListenerPrimary(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public class PipeListenerSecondary : ListenerSecondary public class PipeListenerSecondary : ListenerSecondary
{ {
public PipeListenerSecondary(IMemoryPool memory) : base(memory) public PipeListenerSecondary(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public class TcpListener : Listener public class TcpListener : Listener
{ {
public TcpListener(IMemoryPool memory) : base(memory) public TcpListener(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public class TcpListenerPrimary : ListenerPrimary public class TcpListenerPrimary : ListenerPrimary
{ {
public TcpListenerPrimary(IMemoryPool memory) : base(memory) public TcpListenerPrimary(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
/// </summary> /// </summary>
public class TcpListenerSecondary : ListenerSecondary public class TcpListenerSecondary : ListenerSecondary
{ {
public TcpListenerSecondary(IMemoryPool memory) : base(memory) public TcpListenerSecondary(ServiceContext serviceContext) : base(serviceContext)
{ {
} }

View File

@ -8,6 +8,7 @@ using System.Diagnostics;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Dnx.Runtime;
namespace Microsoft.AspNet.Server.Kestrel namespace Microsoft.AspNet.Server.Kestrel
{ {
@ -18,6 +19,7 @@ namespace Microsoft.AspNet.Server.Kestrel
{ {
private static Action<object, object> _objectCallbackAdapter = (callback, state) => ((Action<object>)callback).Invoke(state); private static Action<object, object> _objectCallbackAdapter = (callback, state) => ((Action<object>)callback).Invoke(state);
private KestrelEngine _engine; private KestrelEngine _engine;
private readonly IApplicationShutdown _appShutdown;
private Thread _thread; private Thread _thread;
private UvLoopHandle _loop; private UvLoopHandle _loop;
private UvAsyncHandle _post; private UvAsyncHandle _post;
@ -29,9 +31,10 @@ namespace Microsoft.AspNet.Server.Kestrel
private bool _stopImmediate = false; private bool _stopImmediate = false;
private ExceptionDispatchInfo _closeError; private ExceptionDispatchInfo _closeError;
public KestrelThread(KestrelEngine engine) public KestrelThread(KestrelEngine engine, ServiceContext serviceContext)
{ {
_engine = engine; _engine = engine;
_appShutdown = serviceContext.AppShutdown;
_loop = new UvLoopHandle(); _loop = new UvLoopHandle();
_post = new UvAsyncHandle(); _post = new UvAsyncHandle();
_thread = new Thread(ThreadStart); _thread = new Thread(ThreadStart);
@ -226,7 +229,7 @@ namespace Microsoft.AspNet.Server.Kestrel
_closeError = ExceptionDispatchInfo.Capture(ex); _closeError = ExceptionDispatchInfo.Capture(ex);
// Request shutdown so we can rethrow this exception // Request shutdown so we can rethrow this exception
// in Stop which should be observable. // in Stop which should be observable.
_engine.AppShutdown.RequestShutdown(); _appShutdown.RequestShutdown();
} }
} }

View File

@ -14,6 +14,8 @@ namespace Microsoft.AspNet.Server.Kestrel
{ {
public class KestrelEngine : IDisposable public class KestrelEngine : IDisposable
{ {
private readonly ServiceContext _serviceContext;
public KestrelEngine(ILibraryManager libraryManager, IApplicationShutdown appShutdownService) public KestrelEngine(ILibraryManager libraryManager, IApplicationShutdown appShutdownService)
: this(appShutdownService) : this(appShutdownService)
{ {
@ -68,21 +70,23 @@ namespace Microsoft.AspNet.Server.Kestrel
private KestrelEngine(IApplicationShutdown appShutdownService) private KestrelEngine(IApplicationShutdown appShutdownService)
{ {
AppShutdown = appShutdownService; _serviceContext = new ServiceContext
{
AppShutdown = appShutdownService,
Memory = new MemoryPool()
};
Threads = new List<KestrelThread>(); Threads = new List<KestrelThread>();
Memory = new MemoryPool();
} }
public Libuv Libuv { get; private set; } public Libuv Libuv { get; private set; }
public IMemoryPool Memory { get; set; }
public IApplicationShutdown AppShutdown { get; private set; }
public List<KestrelThread> Threads { get; private set; } public List<KestrelThread> Threads { get; private set; }
public void Start(int count) public void Start(int count)
{ {
for (var index = 0; index != count; ++index) for (var index = 0; index != count; ++index)
{ {
Threads.Add(new KestrelThread(this)); Threads.Add(new KestrelThread(this, _serviceContext));
} }
foreach (var thread in Threads) foreach (var thread in Threads)
@ -122,16 +126,16 @@ namespace Microsoft.AspNet.Server.Kestrel
if (single) if (single)
{ {
var listener = usingPipes ? var listener = usingPipes ?
(Listener) new PipeListener(Memory) : (Listener) new PipeListener(_serviceContext) :
new TcpListener(Memory); new TcpListener(_serviceContext);
listeners.Add(listener); listeners.Add(listener);
listener.StartAsync(scheme, host, port, thread, application).Wait(); listener.StartAsync(scheme, host, port, thread, application).Wait();
} }
else if (first) else if (first)
{ {
var listener = usingPipes var listener = usingPipes
? (ListenerPrimary) new PipeListenerPrimary(Memory) ? (ListenerPrimary) new PipeListenerPrimary(_serviceContext)
: new TcpListenerPrimary(Memory); : new TcpListenerPrimary(_serviceContext);
listeners.Add(listener); listeners.Add(listener);
listener.StartAsync(pipeName, scheme, host, port, thread, application).Wait(); listener.StartAsync(pipeName, scheme, host, port, thread, application).Wait();
@ -139,8 +143,8 @@ namespace Microsoft.AspNet.Server.Kestrel
else else
{ {
var listener = usingPipes var listener = usingPipes
? (ListenerSecondary) new PipeListenerSecondary(Memory) ? (ListenerSecondary) new PipeListenerSecondary(_serviceContext)
: new TcpListenerSecondary(Memory); : new TcpListenerSecondary(_serviceContext);
listeners.Add(listener); listeners.Add(listener);
listener.StartAsync(pipeName, thread, application).Wait(); listener.StartAsync(pipeName, thread, application).Wait();
} }

View File

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Dnx.Runtime;
namespace Microsoft.AspNet.Server.Kestrel
{
public class ServiceContext
{
public IApplicationShutdown AppShutdown { get; set; }
public IMemoryPool Memory { get; set; }
}
}