diff --git a/python/ycm/client/base_request.py b/python/ycm/client/base_request.py index 4c46a5d9..d67836a5 100644 --- a/python/ycm/client/base_request.py +++ b/python/ycm/client/base_request.py @@ -20,10 +20,15 @@ import vim import json import requests +from retries import retries from requests_futures.sessions import FuturesSession +from concurrent.futures import ThreadPoolExecutor from ycm import vimsupport HEADERS = {'content-type': 'application/json'} +# TODO: This TPE might be the reason we're shutting down slowly. It seems that +# it waits for all worker threads to stop before letting the interpreter exit. +EXECUTOR = ThreadPoolExecutor( max_workers = 4 ) class ServerError( Exception ): def __init__( self, message ): @@ -57,12 +62,24 @@ class BaseRequest( object ): # This returns a future! Use JsonFromFuture to get the value. @staticmethod def PostDataToHandlerAsync( data, handler ): - return BaseRequest.session.post( _BuildUri( handler ), - data = json.dumps( data ), - headers = HEADERS ) + def PostData( data, handler ): + return BaseRequest.session.post( _BuildUri( handler ), + data = json.dumps( data ), + headers = HEADERS ) + + @retries( 3, delay = 0.5 ) + def DelayedPostData( data, handler ): + return requests.post( _BuildUri( handler ), + data = json.dumps( data ), + headers = HEADERS ) + + if not _CheckServerIsHealthyWithCache(): + return EXECUTOR.submit( DelayedPostData, data, handler ) + + return PostData( data, handler ) - session = FuturesSession( max_workers = 4 ) + session = FuturesSession( executor = EXECUTOR ) server_location = 'http://localhost:6666' @@ -102,3 +119,22 @@ def _BuildUri( handler ): return ''.join( [ BaseRequest.server_location, '/', handler ] ) +SERVER_HEALTHY = False + +def _CheckServerIsHealthyWithCache(): + global SERVER_HEALTHY + + def _ServerIsHealthy(): + response = requests.get( _BuildUri( 'healthy' ) ) + response.raise_for_status() + return response.json() + + if SERVER_HEALTHY: + return True + + try: + SERVER_HEALTHY = _ServerIsHealthy() + return SERVER_HEALTHY + except: + return False + diff --git a/python/ycm/client/event_notification.py b/python/ycm/client/event_notification.py index 62c0fa65..c39a4f43 100644 --- a/python/ycm/client/event_notification.py +++ b/python/ycm/client/event_notification.py @@ -17,8 +17,6 @@ # You should have received a copy of the GNU General Public License # along with YouCompleteMe. If not, see . -import traceback -from ycm import vimsupport from ycm.client.base_request import BaseRequest, BuildRequestData @@ -35,15 +33,7 @@ class EventNotification( BaseRequest ): request_data.update( self._extra_data ) request_data[ 'event_name' ] = self._event_name - # On occasion, Vim tries to send event notifications to the server before - # it's up. This causes intrusive exception messages to interrupt the user. - # While we do want to log these exceptions just in case, we post them - # quietly to the Vim message log because nothing bad will happen if the - # server misses some events and we don't want to annoy the user. - try: - self.PostDataToHandlerAsync( request_data, 'event_notification' ) - except: - vimsupport.EchoText( traceback.format_exc() ) + self.PostDataToHandlerAsync( request_data, 'event_notification' ) def SendEventNotificationAsync( event_name, extra_data = None ):