Browse Source

Async requst now restart timer if it re-submits a request in finish(). Also, will 'fake' timeout 2 times before calling the final timeout(). This allows us to see timeouts on the server and only timeout() for the most serious of problems.

Josh Wilson 19 years ago
parent
commit
3f498d6ee8
1 changed files with 31 additions and 6 deletions
  1. 31 6
      direct/src/distributed/AsyncRequest.py

+ 31 - 6
direct/src/distributed/AsyncRequest.py

@@ -5,6 +5,7 @@ from direct.showbase.DirectObject import DirectObject
 from ConnectionRepository import *
 from ConnectionRepository import *
 
 
 DefaultTimeout = 8.0
 DefaultTimeout = 8.0
+TimeoutFailureCount = 2
 if __debug__:
 if __debug__:
     ForceTimeout = config.GetFloat("async-request-timeout", -1.0)
     ForceTimeout = config.GetFloat("async-request-timeout", -1.0)
     BreakOnTimeout = config.GetBool("async-request-break-on-timeout", 0)
     BreakOnTimeout = config.GetBool("async-request-break-on-timeout", 0)
@@ -70,13 +71,14 @@ class AsyncRequest(DirectObject):
         #DirectObject.DirectObject.__init__(self)
         #DirectObject.DirectObject.__init__(self)
         self.air=air
         self.air=air
         self.replyToChannelId=replyToChannelId
         self.replyToChannelId=replyToChannelId
+        self.timeoutTask = None
+        self._timeoutCount = TimeoutFailureCount
         self.neededObjects={}
         self.neededObjects={}
         if __debug__:
         if __debug__:
             if ForceTimeout >= 0.0:
             if ForceTimeout >= 0.0:
                 timeout = ForceTimeout
                 timeout = ForceTimeout
-        self.timeoutTask=taskMgr.doMethodLater(
-            timeout, self.timeout, "AsyncRequestTimer-%s"%(id(self,)))
-
+        self.startTimeOut(timeout)
+        
     def delete(self):
     def delete(self):
         assert self.notify.debugCall()
         assert self.notify.debugCall()
         assert not self.__deleted
         assert not self.__deleted
@@ -84,7 +86,7 @@ class AsyncRequest(DirectObject):
             self.__deleted=True
             self.__deleted=True
         _removeActiveAsyncRequest(self)
         _removeActiveAsyncRequest(self)
         self.ignoreAll()
         self.ignoreAll()
-        taskMgr.remove(self.timeoutTask)
+        self.cancelTimeOut()
         del self.timeoutTask
         del self.timeoutTask
         messenger.send(self.deletingMessage, [])
         messenger.send(self.deletingMessage, [])
         if 0:
         if 0:
@@ -102,6 +104,25 @@ class AsyncRequest(DirectObject):
         del self.replyToChannelId
         del self.replyToChannelId
         #DirectObject.DirectObject.delete(self)
         #DirectObject.DirectObject.delete(self)
 
 
+    def startTimeOut(self, timeout = None):
+        if timeout:
+            self._timeoutTime = timeout
+        self.cancelTimeOut()
+        self.timeoutTask=taskMgr.doMethodLater(
+            self._timeoutTime, self._timeout, "AsyncRequestTimer-%s"%(id(self,)))
+
+    def cancelTimeOut(self):
+        if self.timeoutTask:
+            taskMgr.remove(self.timeoutTask)
+
+    def _timeout(self, task):
+        self._timeoutCount -= 1
+        if not self._timeoutCount:
+            self.timeout(task)
+        else:
+            assert self.notify.debug('Timed out. Trying %d more time(s) : %s' % (self._timeoutCount + 1, `self.neededObjects`))
+            self.startTimeOut()
+            
     def timeout(self, task):
     def timeout(self, task):
         """
         """
         If this is called we have not gotten the needed objects in the timeout
         If this is called we have not gotten the needed objects in the timeout
@@ -159,7 +180,8 @@ class AsyncRequest(DirectObject):
                 "doFieldResponse-%s"%(context,),
                 "doFieldResponse-%s"%(context,),
                 self._checkCompletion, [key])
                 self._checkCompletion, [key])
             self.air.queryObjectField(dclassName, fieldName, doId, context)
             self.air.queryObjectField(dclassName, fieldName, doId, context)
-
+            self.startTimeOut()
+            
     def askForObject(self, doId, context=None):
     def askForObject(self, doId, context=None):
         """
         """
         Request an already created object, i.e. read from database.
         Request an already created object, i.e. read from database.
@@ -179,6 +201,7 @@ class AsyncRequest(DirectObject):
                 "doRequestResponse-%s"%(context,),
                 "doRequestResponse-%s"%(context,),
                 self._checkCompletion, [None])
                 self._checkCompletion, [None])
             self.air.queryObjectAll(doId, context)
             self.air.queryObjectAll(doId, context)
+            self.startTimeOut()
 
 
     #def addInterestInObject(self, doId, context=None):
     #def addInterestInObject(self, doId, context=None):
     #    """
     #    """
@@ -232,6 +255,7 @@ class AsyncRequest(DirectObject):
         ##         "doRequestResponse-%s"%(context,), self._checkCompletion, [name])
         ##         "doRequestResponse-%s"%(context,), self._checkCompletion, [name])
         self.air.requestDatabaseGenerate(
         self.air.requestDatabaseGenerate(
             className, context, databaseId=databaseId, values=values)
             className, context, databaseId=databaseId, values=values)
+        self.startTimeOut()
 
 
     def createObjectId(self, name, className, values=None, context=None):
     def createObjectId(self, name, className, values=None, context=None):
         """
         """
@@ -255,7 +279,8 @@ class AsyncRequest(DirectObject):
             self.air.getDatabaseGenerateResponseEvent(context),
             self.air.getDatabaseGenerateResponseEvent(context),
             self._checkCompletion, [name, None])
             self._checkCompletion, [name, None])
         self.air.requestDatabaseGenerate(className, context, values=values)
         self.air.requestDatabaseGenerate(className, context, values=values)
-
+        self.startTimeOut()
+        
     def _doCreateObject(self, name, className, values, doId):
     def _doCreateObject(self, name, className, values, doId):
         assert self.notify.debugCall()
         assert self.notify.debugCall()
         assert not self.__deleted
         assert not self.__deleted