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:
Strahinja Val Markovic 2013-10-02 17:09:25 -07:00
parent 9742302cbd
commit 7248979bb4
2 changed files with 41 additions and 15 deletions

View File

@ -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

View File

@ -17,8 +17,6 @@
# You should have received a copy of the GNU General Public License
# 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
@ -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 ):