public override Task ProcessRequest(IRequestContext context) { if (Disabled) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"Least connected load balancer '{Name}' is disabled"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " is disabled"; context.Outgoing.SendHeaders(context); })); } var output = OutputNodes .Where(o => !o.Disabled && o.Node != null) .OrderBy(o => o.ConnectionCount) .FirstOrDefault(); if (output == null) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"Least connected load balancer '{Name}' has no enabled outputs"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " has no enabled outputs"; context.Outgoing.SendHeaders(context); })); } context.Log?.Log(LogType.Step, LogLevel.Standard, () => $"Least connected load balancer '{Name}' routing request to '{output.Name}'"); output.IncrementConnectionCount(); var trafficAnalyticInfo = output.TrafficAnalytics.BeginRequest(); var task = output.Node.ProcessRequest(context); if (task == null) { output.TrafficAnalytics.EndRequest(trafficAnalyticInfo); return(null); } return(task.ContinueWith(t => { output.TrafficAnalytics.EndRequest(trafficAnalyticInfo); output.DecrementConnectionCount(); })); }
public override Task ProcessRequest(IRequestContext context) { if (Disabled) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"Sticky session load balancer '{Name}' is disabled by configuration"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " is disabled"; context.Outgoing.SendHeaders(context); })); } if (string.IsNullOrEmpty(SessionCookie)) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"Sticky session load balancer '{Name}' has no cookie name configured"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " has no session cookie configured"; context.Outgoing.SendHeaders(context); })); } var cookies = context.Incoming.GetCookies(); var sessionId = cookies.ContainsKey(SessionCookie) ? cookies[SessionCookie] : null; TrafficAnalyticInfo trafficAnalyticInfo; if (string.IsNullOrEmpty(sessionId)) { context.Log?.Log(LogType.Logic, LogLevel.Detailed, () => $"No session cookie in incoming request"); var output = OutputNodes .Where(o => !o.Disabled && o.Node != null) .OrderBy(o => o.ConnectionCount) .ThenBy(o => o.SessionCount) .FirstOrDefault(); if (output == null) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"Sticky session load balancer '{Name}' has no enabled outputs"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " has no enabled outputs"; context.Outgoing.SendHeaders(context); })); } trafficAnalyticInfo = output.TrafficAnalytics.BeginRequest(); output.IncrementConnectionCount(); context.Outgoing.OnSendHeaders.Add(ctx => { context.Log?.Log(LogType.Logic, LogLevel.Detailed, () => $"Sticky session load balancer '{Name}' looking for a Set-Cookie header in the response"); if (ctx.Outgoing.Headers.TryGetValue("Set-Cookie", out var setCookieHeaders)) { var setSession = setCookieHeaders.FirstOrDefault(c => c.StartsWith(SessionCookie + "=")); if (setSession != null) { context.Log?.Log(LogType.Logic, LogLevel.Detailed, () => $"A session cookie was found, this caller will be sticky to output '{output.Name}'"); var start = SessionCookie.Length + 1; var end = setSession.IndexOf(';', start); if (end < 0) { end = setSession.Length; } sessionId = setSession.Substring(start, end - start); output.IncrementSessionCount(); lock (_sessionNodes) _sessionNodes[sessionId] = output; lock (_sessionExpiry) _sessionExpiry.Add(new Tuple <string, DateTime>(sessionId, DateTime.UtcNow + SessionDuration)); } } }); context.Log?.Log(LogType.Step, LogLevel.Standard, () => $"Sticky session load balancer '{Name}' routing request to '{output.Name}'"); var task = output.Node.ProcessRequest(context); if (task == null) { output.TrafficAnalytics.EndRequest(trafficAnalyticInfo); return(null); } return(task.ContinueWith(t => { output.TrafficAnalytics.EndRequest(trafficAnalyticInfo); output.DecrementConnectionCount(); })); } NodeOutput sessionOutput; bool hasSession; lock (_sessionNodes) hasSession = _sessionNodes.TryGetValue(sessionId, out sessionOutput); if (!hasSession) { context.Log?.Log(LogType.Logic, LogLevel.Standard, () => $"No session found for session id {sessionId}"); sessionOutput = OutputNodes .Where(o => !o.Disabled && o.Node != null) .OrderBy(o => o.ConnectionCount) .ThenBy(o => o.SessionCount) .FirstOrDefault(); if (sessionOutput == null) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"Sticky session load balancer '{Name}' has no enabled outputs"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " has no enabled outputs"; context.Outgoing.SendHeaders(context); })); } context.Log?.Log(LogType.Logic, LogLevel.Standard, () => $"Sticking this session to least connected output '{sessionOutput.Name}'"); sessionOutput.IncrementSessionCount(); lock (_sessionNodes) _sessionNodes[sessionId] = sessionOutput; lock (_sessionExpiry) _sessionExpiry.Add(new Tuple <string, DateTime>(sessionId, DateTime.UtcNow + SessionDuration)); } if (sessionOutput.Disabled) { context.Log?.Log(LogType.Logic, LogLevel.Important, () => $"The sticky output '{sessionOutput.Name}' for load balancer '{Name}' for session id {sessionId} is disabled"); return(Task.Run(() => { context.Outgoing.StatusCode = 503; context.Outgoing.ReasonPhrase = "Balancer " + Name + " sticky output is down"; context.Outgoing.SendHeaders(context); })); } context.Log?.Log(LogType.Step, LogLevel.Standard, () => $"Sticky session load balancer '{Name}' routing request to '{sessionOutput.Name}'"); trafficAnalyticInfo = sessionOutput.TrafficAnalytics.BeginRequest(); sessionOutput.IncrementConnectionCount(); var sessionTask = sessionOutput.Node.ProcessRequest(context); if (sessionTask == null) { sessionOutput.TrafficAnalytics.EndRequest(trafficAnalyticInfo); return(null); } return(sessionTask.ContinueWith(t => { sessionOutput.TrafficAnalytics.EndRequest(trafficAnalyticInfo); sessionOutput.DecrementConnectionCount(); })); }
/// <summary> /// Executes the block /// </summary> public override void Execute() { var connectingNode = InputNodes[0].ConnectingNode as BlockOutputNode; if (connectingNode == null || connectingNode.Object == null) { return; } var signalIndex = 0; OutputNodes[0].Object.Clear(); OutputNodes[1].Object.Clear(); OutputNodes[2].Object.Clear(); OutputNodes[3].Object.Clear(); foreach (var signal in connectingNode.Object) { signalIndex++; var name = signal.Name; if (!string.IsNullOrEmpty(name)) { name += " - "; } else { name = Resources.Signal + " " + signalIndex + " - "; } var decompositionLevels = DWT.ExecuteDWT(signal, _motherWavelet, Level, ExtensionMode); foreach (var level in decompositionLevels) { var apxSignal = signal.Copy(); apxSignal.Name = name + Resources.ApproximationLevel + " " + (level.Index + 1); apxSignal.Samples = level.Approximation; OutputNodes[0].Object.Add(apxSignal); if (Rescale) { var rescaledApx = RescaleSignal(apxSignal, signal, level); OutputNodes[3].Object.Add(rescaledApx); } else { OutputNodes[3].Object.Add(apxSignal); } var detSignal = signal.Copy(); detSignal.Name = name + Resources.DetailsLevel + " " + (level.Index + 1); detSignal.Samples = level.Details; OutputNodes[1].Object.Add(detSignal); if (Rescale) { var rescaledDet = RescaleSignal(detSignal, signal, level); OutputNodes[3].Object.Add(rescaledDet); } else { OutputNodes[3].Object.Add(detSignal); } } var reconstruction = DWT.ExecuteIDWT(decompositionLevels, _motherWavelet, Level); var recSignal = signal.Copy(); recSignal.Name = name + Resources.Reconstruction; recSignal.Samples = reconstruction; OutputNodes[2].Object.Add(recSignal); OutputNodes[3].Object.Add(recSignal); } if (!Cascade) { return; } foreach (var output in OutputNodes.Where(output => output.ConnectingNode != null)) { output.ConnectingNode.Root.Execute(); } }