private void OnRequestReceived(HttpServer server, HttpListenerContext context) { RequestHandler handler; var commandPath = UnknownRequestHandler.Path; var path = context.Request.Url.AbsolutePath; if (path.Length > 1) { var firstSlash = path.IndexOf('/', 1); commandPath = (firstSlash > 0 ? path.Substring(0, firstSlash) : path); } if (!this.requestHandlers.TryGetValue(commandPath, out handler)) { handler = this.requestHandlers[UnknownRequestHandler.Path]; } var request = new Request(context, this.DataManager.MemoryStreamManager, this, handler); if (handler.TaskPool == RequestHandler.TaskPoolDesired.None) { Task.Factory.StartNew(() => this.ExecuteHandler(request)); } else { // The task runner deals with exceptions so there's no reason to wait here. #pragma warning disable 4014 handler.taskRunner.RunAsync(() => this.ExecuteHandler(request)); #pragma warning restore 4014 } }
/// <summary> /// Constructor. /// </summary> /// <param name="hostname">Hostname to listen on ("+" to listen on all addresses).</param> /// <param name="port">Port number to listen on. If 0 a random available port will be selected.</param> /// <param name="dataManager">Data Manager to retrieve data from.</param> /// <param name="requestHandlers">Additional request handlers to use.</param> /// <param name="maxConcurrentQueries">Maximum number of queries which can be processed in parallel</param> public Server(string hostname, ushort port, DataManager dataManager, IList<RequestHandler> requestHandlers, int maxConcurrentQueries) { if (port == 0) { this.FindAvailablePort(); } else { this.Port = port; } if (dataManager == null) { throw new ArgumentNullException("dataManager"); } this.Hostname = Dns.GetHostEntry("localhost").HostName; this.DataManager = dataManager; // TODO: move to JSON config. this.ServerList = new ServerList {ExpirationTime = TimeSpan.FromMinutes(10)}; this.MinimumResponseSizeToCompress = DefaultMinimumResponseSizeToCompress; if (maxConcurrentQueries <= 0) { maxConcurrentQueries = Environment.ProcessorCount; } this.maxConcurrentQueriesPerTaskPool = maxConcurrentQueries; this.taskRunner = new SemaphoreTaskRunner(maxConcurrentQueries); this.AddHandler(new PingRequestHandler()); this.AddHandler(new UnknownRequestHandler()); this.AddHandler(new BatchQueryRequestHandler(this)); this.AddHandler(new CountersRequestHandler(this)); this.AddHandler(new ListServersRequestHandler(this.ServerList)); this.AddHandler(new RegisterRequestHandler(this.ServerList)); this.AddHandler(new TransferRequestHandler(this.DataManager)); this.AddHandler(new WriteRequestHandler(this)); if (requestHandlers != null) { foreach (var handler in requestHandlers) { this.AddHandler(handler); } } // do not use 'this.Hostname' because, if it was localhost, we do only want to listen on loopback, but // GetHostEntry above will transform that into our full computer name and not honor this. Basically this // is some goofy voodoo magic. this.server = new HttpServer(hostname, this.Port); this.server.RequestReceived += this.OnRequestReceived; }
public void Dispose() { this.Stop(); if (this.aggregationPoller != null) { this.aggregationPoller.Dispose(); this.aggregationPoller = null; } if (this.server != null) { this.server.Dispose(); this.server = null; } if (this.registrationClient != null) { this.registrationClient.Dispose(); this.registrationClient = null; } foreach (var handler in this.requestHandlers.Values) { if (handler.taskRunner != this.taskRunner) { handler.taskRunner.Dispose(); handler.taskRunner = null; } } if (this.ServerList != null) { this.ServerList.Dispose(); this.ServerList = null; } if (this.taskRunner != null) { this.taskRunner.Dispose(); this.taskRunner = null; } }