#NEWLINE# def _do_blocking_operation( self , function , timeout_sec = VOLUME_DEFAULT_TIMEOUT , sleep = None , **kwargs ) : #NEWLINE# #INDENT# "\n        Perform a GCE operation, blocking until the operation completes.\n\n        This will call `function` with the passed in keyword arguments plus\n        additional keyword arguments for project and zone which come from the\n        private member variables with the same name. It is expected that\n        `function` returns an object that has an `execute()` method that\n        returns a GCE operation resource dict.\n\n        This function will then poll the operation until it reaches\n        state 'DONE' or times out, and then returns the final\n        operation resource dict. The value for the timeout was chosen\n        by testing the running time of our GCE operations. Sometimes\n        certain operations can take over 30s but they rarely, if ever,\n        take over a minute.\n\n        Timeouts should not be caught here but should propogate up the\n        stack and the node will eventually retry the operation via the\n        convergence loop.\n\n        :param function: Callable that takes keyword arguments project and\n            zone, and returns an executable that results in a GCE operation\n            resource dict as described above.\n        :param int timeout_sec: The maximum amount of time to wait in seconds\n            for the operation to complete.\n        :param sleep: A callable that has the same signature and function as\n            ``time.sleep``. Only intended to be used in tests.\n        :param kwargs: Additional keyword arguments to pass to function.\n\n        :returns dict: A dict representing the concluded GCE operation\n            resource.\n        " #NEWLINE# if ( sleep is None ) : #NEWLINE# #INDENT# sleep = time . sleep #NEWLINE# #UNINDENT# def lock_dropped_sleep( * args , **kwargs ) : #NEWLINE# #INDENT# '\n            A custom sleep function that drops the lock while the actual\n            sleeping is going on.\n            ' #NEWLINE# self . _lock . release ( ) #NEWLINE# try : #NEWLINE# #INDENT# return sleep ( * args , ** kwargs ) #NEWLINE# #UNINDENT# finally : #NEWLINE# #INDENT# self . _lock . acquire ( ) #NEWLINE# #UNINDENT# #UNINDENT# args = dict ( project = self . _project , zone = self . _zone ) #NEWLINE# args . update ( kwargs ) #NEWLINE# with self . _lock : #NEWLINE# #INDENT# operation = function ( ** args ) . execute ( ) #NEWLINE# return wait_for_operation ( self . _compute , operation , ( [ 1 ] * timeout_sec ) , lock_dropped_sleep )