CherryPy 12 removed Response timeout parameter
CherryPy Response objects used to have a `timeout` parameter that defaulted to 300 seconds.  We occasionally needed more time that this for responses, so would reset the timer in the `utility/progress/setResponseTimeLimit` function.  As of CherryPy 12.0, the Response objects no longer have this parameter (see https://github.com/cherrypy/cherrypy/issues/1625).

Since we only ever use this to extend the timeout, at least in core code, we could make this a no-op if the Response object doesn't have a timeout property.  Further, to warn external code that uses this function, if called with non-default parameters, we could emit a warning that this feature is no longer available through CherryPy.
diff --git a/girder/utility/progress.py b/girder/utility/progress.py
index 681b8c043..56b98e73c 100644
--- a/girder/utility/progress.py
+++ b/girder/utility/progress.py
@@ -108,19 +108,25 @@ noProgress = ProgressContext(False)
 def setResponseTimeLimit(duration=600, onlyExtend=True):
     """
     If we are currently within a cherrypy response, extend the time limit.  By
-    default, cherrypy responses will timeout after 300 seconds, so any activity
-    which can take longer should call this function.
+    default, cherrypy (version < 12.0) responses will timeout after 300
+    seconds, so any activity which can take longer should call this function.
 
     Note that for cherrypy responses that include streaming generator
     functions, such as downloads, the timeout is only relevant until the first
     ``yield`` is reached.  As such, long running generator responses do not
     generally need to call this function.
 
+    @deprecated - remove this function once we pin to CherryPy >= 12.0
+
     :param duration: additional duration in seconds to allow for the response.
     :param onlyExtend: if True, only ever increase the timeout.  If False, the
                        new duration always replaces the old one.
     """
-    if cherrypy.response and getattr(cherrypy.response, 'time'):
+    # CherryPy 12.0 no longer has a timeout propery on a response.  Since we
+    # had only been using this to extend the time, if the timeout property is
+    # not present, do nothing.
+    if (cherrypy.response and getattr(cherrypy.response, 'time', None) and
+            getattr(cherrypy.response, 'timeout', None)):
         newTimeout = time.time() - cherrypy.response.time + duration
         if not onlyExtend or newTimeout > cherrypy.response.timeout:
             cherrypy.response.timeout = newTimeout
['girder/utility/progress.py']