Просмотр исходного кода

2004-08-31 Gonzalo Paniagua Javier <[email protected]>

	* HttpRuntime.cs: initialize the response writer when finishing a
	request because it cannot be queued. Under heavy load we made new
	requests be processed before the ones that might be queued. This is
	no longer the case.

	* QueueManager.cs: instead of queueing/dequeuing separately, we now
	have a single method that does everything needed to decide which one
	will be the next request processed.

svn path=/trunk/mcs/; revision=33113
Gonzalo Paniagua Javier 21 лет назад
Родитель
Сommit
e05d2fdb42

+ 12 - 0
mcs/class/System.Web/System.Web/ChangeLog

@@ -1,3 +1,15 @@
+
+2004-08-31 Gonzalo Paniagua Javier <[email protected]>
+
+	* HttpRuntime.cs: initialize the response writer when finishing a
+	request because it cannot be queued. Under heavy load we made new
+	requests be processed before the ones that might be queued. This is
+	no longer the case.
+
+	* QueueManager.cs: instead of queueing/dequeuing separately, we now
+	have a single method that does everything needed to decide which one
+	will be the next request processed.
+
 2004-08-27 Gonzalo Paniagua Javier <[email protected]>
 
 	* HttpRuntime.cs: removed initializations to null in .cctor. Prevent

+ 18 - 20
mcs/class/System.Web/System.Web/HttpRuntime.cs

@@ -179,6 +179,8 @@ namespace System.Web {
 				context.Response.FinalFlush ();
 			}
 
+			/*
+			 * This is not being used. OnFirstRequestEnd is empty.
 			if (!_firstRequestExecuted) {
 				lock (this) {
 					if (!_firstRequestExecuted) {
@@ -187,6 +189,7 @@ namespace System.Web {
 					}
 				}
 			}
+			*/
 
 			Interlocked.Decrement(ref _activeRequests);
 
@@ -231,6 +234,7 @@ namespace System.Web {
 			HttpContext context = new HttpContext (wr);
 			HttpException exception = new HttpException (503, "Service unavailable");
 			Interlocked.Increment (ref _runtime._activeRequests);
+			context.Response.InitializeWriter ();
 			_runtime.FinishRequest (context, exception);
 		}
 
@@ -276,7 +280,7 @@ namespace System.Web {
 							_firstRequestStartTime = DateTime.Now;
 							OnFirstRequestStart(context);
 							_firstRequestStarted = true;
-						}						
+						}
 					}
 				}
 
@@ -311,38 +315,32 @@ namespace System.Web {
 		void TryExecuteQueuedRequests ()
 		{
 			// Wait for pending jobs to start
-			if (Interlocked.CompareExchange (ref pendingCallbacks, 3, 3) == 3) {
-				return;
-			}
-
-			if (queueManager == null)
-				return;
-
-			if (!queueManager.CanExecuteRequest (false)) {
+			if (Interlocked.CompareExchange (ref pendingCallbacks, 3, 3) == 3)
 				return;
-			}
 
-			HttpWorkerRequest wr = queueManager.Dequeue ();
-			if (wr == null) {
+			HttpWorkerRequest wr = queueManager.GetNextRequest (null);
+			if (wr == null)
 				return;
-			}
 
 			Interlocked.Increment (ref pendingCallbacks);
 			ThreadPool.QueueUserWorkItem (doRequestCallback, wr);
 			TryExecuteQueuedRequests ();
 		}
 
-		public static void ProcessRequest (HttpWorkerRequest Request)
+		public static void ProcessRequest (HttpWorkerRequest request)
 		{
-			if (Request == null)
-				throw new ArgumentNullException ("Request");
+			if (request == null)
+				throw new ArgumentNullException ("request");
 
 			QueueManager mgr = _runtime.queueManager;
-			if (!_runtime._firstRequestExecuted || mgr == null || mgr.CanExecuteRequest (false)) {
-				_runtime.InternalExecuteRequest (Request);
-			} else {
-				_runtime.queueManager.Queue (Request);
+			if (_runtime._firstRequestStarted && mgr != null) {
+				request = mgr.GetNextRequest (request);
+				// We're busy, return immediately
+				if (request == null)
+					return;
 			}
+
+			_runtime.InternalExecuteRequest (request);
 		}
 
 #if NET_1_1

+ 37 - 15
mcs/class/System.Web/System.Web/QueueManager.cs

@@ -4,7 +4,7 @@
 // Authors:
 //	Gonzalo Paniagua Javier ([email protected])
 //
-// (C) 2003 Novell, Inc (http://www.novell.com)
+// (C) 2003,2004 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -53,35 +53,57 @@ namespace System.Web
 			queue = new Queue (queueLimit);
 		}
 
-		// TODO: handle local connections
-		public bool CanExecuteRequest (bool local)
+		// TODO: handle local connections, just check for 127.0.0.1
+		bool CanExecuteRequest ()
 		{
 			if (disposing)
 				return false;
 				
 			int threads, cports;
 			ThreadPool.GetAvailableThreads (out threads, out cports);
-			return (threads > minFree) || (local && threads > minLocalFree);
+			return (threads > minFree); // || (local && threads > minLocalFree);
 		}
-		
-		public void Queue (HttpWorkerRequest wr)
+
+		public HttpWorkerRequest GetNextRequest (HttpWorkerRequest req)
 		{
+			if (!CanExecuteRequest ()) {
+				if (req != null) {
+					lock (queue) {
+						Queue (req);
+					}
+				}
+
+				return null;
+			}
+
+			HttpWorkerRequest result;
 			lock (queue) {
-				if (queue.Count < queueLimit) {
-					queue.Enqueue (wr);
-					return;
+				result = Dequeue ();
+				if (result != null) {
+					if (req != null)
+						Queue (req);
+				} else {
+					result = req;
 				}
 			}
 
+			return result;
+		}
+		
+		void Queue (HttpWorkerRequest wr)
+		{
+			if (queue.Count < queueLimit) {
+				queue.Enqueue (wr);
+				return;
+			}
+
 			HttpRuntime.FinishUnavailable (wr);
 		}
 
-		public HttpWorkerRequest Dequeue ()
+		HttpWorkerRequest Dequeue ()
 		{
-			lock (queue) {
-				if (queue.Count > 0)
-					return (HttpWorkerRequest) queue.Dequeue ();
-			}
+			if (queue.Count > 0)
+				return (HttpWorkerRequest) queue.Dequeue ();
 
 			return null;
 		}
@@ -93,7 +115,7 @@ namespace System.Web
 
 			disposing = true;
 			HttpWorkerRequest wr;
-			while ((wr = Dequeue ()) != null)
+			while ((wr = GetNextRequest (null)) != null)
 				HttpRuntime.FinishUnavailable (wr);
 
 			queue = null;