You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2006/10/14 10:13:09 UTC

svn commit: r463899 - in /db/derby/code/branches/10.1/java: engine/org/apache/derby/iapi/services/daemon/ engine/org/apache/derby/impl/services/daemon/ testing/org/apache/derbyTesting/unitTests/services/

Author: kahatlen
Date: Sat Oct 14 01:13:06 2006
New Revision: 463899

URL: http://svn.apache.org/viewvc?view=rev&rev=463899
Log:
DERBY-989: unit/daemonService.unit fails intermittently: 'ran out of time'

Merged fix from trunk.

Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/services/daemon/DaemonService.java
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/daemon/BasicDaemon.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/unitTests/services/T_DaemonService.java

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/services/daemon/DaemonService.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/services/daemon/DaemonService.java?view=diff&rev=463899&r1=463898&r2=463899
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/services/daemon/DaemonService.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/services/daemon/DaemonService.java Sat Oct 14 01:13:06 2006
@@ -28,10 +28,18 @@
   asynchronous I/O and general clean up.  It should not be used as a general
   worker thread for parallel execution.  A DaemonService can be subscribe to by
   many Serviceable objects and a DaemonService will call that object's
-  performWork from time to time.  These performWork method is defined by the
+  performWork from time to time.  The performWork method is defined by the
   client object and should be well behaved - in other words, it should not take
   too long or hog too many resources or deadlock with anyone else.  And it
   cannot (should not) error out.
+
+  <P>It is up to each <code>DaemonService</code> implementation to define its
+  level of service, including
+  <UL>
+  <LI>how quickly and how often the clients should expect to be be serviced
+  <LI>how the clients are prioritized
+  <LI>whether the clients need to tolerate spurious services
+  </UL>
  
   <P>MT - all routines on the interface must be MT-safe.
 
@@ -66,7 +74,12 @@
 
 
 	/**
-		Get rid of a client from the daemon.
+		Get rid of a client from the daemon. If a client is being serviced when
+		the call is made, the implementation may choose whether or not the call
+		should block until the client has completed its work. If the call does
+		not block, the client must be prepared to handle calls to its
+		<code>performWork()</code> method even after <code>unsubscribe()</code>
+		has returned.
 
 		@param clientNumber the number that uniquely identify the client
 	*/

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/daemon/BasicDaemon.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/daemon/BasicDaemon.java?view=diff&rev=463899&r1=463898&r2=463899
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/daemon/BasicDaemon.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/services/daemon/BasicDaemon.java Sat Oct 14 01:13:06 2006
@@ -43,7 +43,7 @@
 	recoverable, they are all lost when the system crashes or is shutdown.
 	System shutdown, even orderly ones, do not wait for daemons to finish its
 	work or empty its queue.  Furthermore, any Serviceable subscriptions,
-	including onDemandOnly, must tolerate spurrious services.  The BasicDaemon
+	including onDemandOnly, must tolerate spurious services.  The BasicDaemon
 	will setup a context manager with no context on it.  The Serviceable
 	object's performWork must provide useful context on the context manager to
 	do its work.  The BasicDaemon will wrap performWork call with try / catch
@@ -164,6 +164,15 @@
 		return clientNumber;
 	}
 
+	/**
+	 * Removes a client from the list of subscribed clients. The call does not
+	 * wait for the daemon to finish the work it is currently performing.
+	 * Therefore, the client must tolerate that its <code>performWork()</code>
+	 * method could be invoked even after the call to
+	 * <code>unsubscribe()</code> has returned (but not more than once).
+	 *
+	 * @param clientNumber client identifier
+	 */
 	public void unsubscribe(int clientNumber)
 	{
 		if (clientNumber < 0 || clientNumber > subscription.size())

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/unitTests/services/T_DaemonService.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/unitTests/services/T_DaemonService.java?view=diff&rev=463899&r1=463898&r2=463899
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/unitTests/services/T_DaemonService.java (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/unitTests/services/T_DaemonService.java Sat Oct 14 01:13:06 2006
@@ -110,6 +110,11 @@
 	*/
 	protected void runTestSet() throws T_Fail
 	{
+		// we don't want t_checkStatus() to hang because of
+		// unsubscribed records from a previous, failed iteration
+		// (DERBY-989)
+		serviceRecord.clear();
+
 		try
 		{
 			/* test basic DaemonService interface */
@@ -243,8 +248,16 @@
 
 		synchronized(s1)
 		{
-			if (save != s1.timesServiced)
-				throw T_Fail.testFailMsg("unsubscribed continue to get serviced");
+			// DERBY-989: The client should not be serviced after it
+			// unsubscribes. However, it might have been in the
+			// process of being serviced when unsubscribe() was
+			// called. Therefore, performWork() can run even after the
+			// save variable was initialized, but only once.
+			int diff = s1.timesServiced - save;
+			// Check that the client has not been serviced more than
+			// once after it unsubscribed.
+			T_Fail.T_ASSERT((diff == 0 || diff == 1),
+							"unsubscribed continue to get serviced");
 
 			// unsubscribed can subscribe again
 			s1.timesServiced = 0;