private HmuxConnection OpenRecycle() { long now = Utils.CurrentTimeMillis(); HmuxConnection channel = null; lock (this) { if (_idleHead != _idleTail) { channel = _idle[_idleHead]; long freeTime = channel.GetIdleStartTime(); _idle[_idleHead] = null; _idleHead = (_idleHead + _idle.Length - 1) % _idle.Length; if (now < freeTime + _loadBalanceIdleTime) { _activeCount++; channel.ClearIdleStartTime(); channel.ToActive(); Trace.TraceInformation("OpenRecycle '{0}'", channel); return(channel); } } } if (channel != null) { if (_log.IsLoggable(EventLogEntryType.Information)) { _log.Info(this + " close idle " + channel + " expire=" + new DateTime(channel.GetIdleStartTime() * 10 + _loadBalanceIdleTime * 10)); } Trace.TraceInformation("closing expired channel '{0}'", channel); channel.CloseImpl(); } Trace.TraceInformation("OpenRecyle return 'null'"); return(null); }
private void DoHmux(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; String sessionId; if (!_isStickySessions) { sessionId = null; } else { sessionId = GetRequestedSessionId(request); } TempBuffer tempBuf = TempBuffer.Allocate(); byte[] buf = tempBuf.GetBuffer(); try { Stream is_ = request.InputStream; int len = is_.Read(buf, 0, buf.Length); bool isComplete; if (len < 0) { isComplete = true; } else if (len < buf.Length) { int sublen = is_.Read(buf, len, 1); if (sublen == 0) //.NET return 0 for Stream.EOF { isComplete = true; } else { len += sublen; isComplete = false; } } else { isComplete = false; } Server client = null; int result = OK | EXIT; HmuxConnection channel = _loadBalancer.OpenServer(sessionId, null); // If everything fails, return an error if (channel == null) { SendNotAvailable(response); return; } client = channel.GetPool(); BufferedStream rs = channel.GetSocketStream(); BufferedStream ws = channel.GetSocketStream(); result = FAIL | EXIT; long requestStartTime = Utils.CurrentTimeMillis(); try { result = HandleRequest(context, request, response, channel, rs, ws, buf, len, isComplete, isComplete); if ((result & STATUS_MASK) == OK) { client.ClearBusy(); return; } else if ((result & STATUS_MASK) == BUSY) { client.Busy(); } else { client.FailSocket(); } } catch (ClientDisconnectException) { _log.Info("Client disconnect detected for '{0}'", channel.GetTraceId()); return; } catch (IOException e) { client.FailSocket(); _log.Error("IOException '{0}': '{1}' {2}", channel.GetTraceId(), e.Message, e.StackTrace); } finally { if ((result & EXIT_MASK) == QUIT) { channel.Free(requestStartTime); } else { channel.Close(); } } // server/2675 if (isComplete && (result & STATUS_MASK) == BUSY || "GET".Equals(request.HttpMethod)) { channel = _loadBalancer.OpenServer(sessionId, client); // If everything fails, return an error if (channel == null) { _log.Info("load-balance failed" + (client != null ? (" for " + client.GetDebugId()) : "")); SendNotAvailable(response); return; } Server client2 = channel.GetPool(); if (_log.IsLoggable(EventLogEntryType.Information)) { _log.Info("load-balance failing over" + (client != null ? (" from " + client.GetDebugId()) : "") + " to " + client2.GetDebugId()); } rs = channel.GetSocketStream(); ws = channel.GetSocketStream(); result = FAIL | EXIT; requestStartTime = Utils.CurrentTimeMillis(); try { result = HandleRequest(context, request, response, channel, rs, ws, buf, len, isComplete, false); if ((result & STATUS_MASK) == OK) { client2.ClearBusy(); return; } else if ((result & STATUS_MASK) == BUSY) { client2.Busy(); } else { client2.FailSocket(); } } catch (IOException e) { client2.FailSocket(); _log.Info("Failover to '{0}' did not succeed '{1}', {2} ", client2.GetDebugId(), e.Message, e.StackTrace); } finally { if ((result & EXIT_MASK) == QUIT) { channel.Free(requestStartTime); } else { channel.Close(); } } } SendNotAvailable(response); } finally { TempBuffer.Free(tempBuf); tempBuf = null; } }