We now handle the starting FileReadyToParse event
The problem was that when you start vim like "vim foo.cc", the FileReadyToParse event is sent to the server before it's actually started up. Basically, a race condition. We _really_ don't want to miss that event. For C++ files, it tells the server to start compiling the file. So now PostDataToHandlerAsync in BaseRequest will retry the request 3 times (with exponential backoff) before failing, thus giving the server time to boot.
This commit is contained in:
parent
9742302cbd
commit
7248979bb4
@ -20,10 +20,15 @@
|
|||||||
import vim
|
import vim
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
from retries import retries
|
||||||
from requests_futures.sessions import FuturesSession
|
from requests_futures.sessions import FuturesSession
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from ycm import vimsupport
|
from ycm import vimsupport
|
||||||
|
|
||||||
HEADERS = {'content-type': 'application/json'}
|
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 ):
|
class ServerError( Exception ):
|
||||||
def __init__( self, message ):
|
def __init__( self, message ):
|
||||||
@ -57,12 +62,24 @@ class BaseRequest( object ):
|
|||||||
# This returns a future! Use JsonFromFuture to get the value.
|
# This returns a future! Use JsonFromFuture to get the value.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def PostDataToHandlerAsync( data, handler ):
|
def PostDataToHandlerAsync( data, handler ):
|
||||||
return BaseRequest.session.post( _BuildUri( handler ),
|
def PostData( data, handler ):
|
||||||
data = json.dumps( data ),
|
return BaseRequest.session.post( _BuildUri( handler ),
|
||||||
headers = HEADERS )
|
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'
|
server_location = 'http://localhost:6666'
|
||||||
|
|
||||||
|
|
||||||
@ -102,3 +119,22 @@ def _BuildUri( handler ):
|
|||||||
return ''.join( [ BaseRequest.server_location, '/', 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
|
||||||
|
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import traceback
|
|
||||||
from ycm import vimsupport
|
|
||||||
from ycm.client.base_request import BaseRequest, BuildRequestData
|
from ycm.client.base_request import BaseRequest, BuildRequestData
|
||||||
|
|
||||||
|
|
||||||
@ -35,15 +33,7 @@ class EventNotification( BaseRequest ):
|
|||||||
request_data.update( self._extra_data )
|
request_data.update( self._extra_data )
|
||||||
request_data[ 'event_name' ] = self._event_name
|
request_data[ 'event_name' ] = self._event_name
|
||||||
|
|
||||||
# On occasion, Vim tries to send event notifications to the server before
|
self.PostDataToHandlerAsync( request_data, 'event_notification' )
|
||||||
# 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() )
|
|
||||||
|
|
||||||
|
|
||||||
def SendEventNotificationAsync( event_name, extra_data = None ):
|
def SendEventNotificationAsync( event_name, extra_data = None ):
|
||||||
|
Loading…
Reference in New Issue
Block a user