Server now shuts down cleanly on VimClose
This commit is contained in:
parent
1730660555
commit
f51a687297
@ -160,6 +160,12 @@ let g:ycm_auto_stop_csharp_server =
|
|||||||
let g:ycm_csharp_server_port =
|
let g:ycm_csharp_server_port =
|
||||||
\ get( g:, 'ycm_csharp_server_port', 2000 )
|
\ get( g:, 'ycm_csharp_server_port', 2000 )
|
||||||
|
|
||||||
|
let g:ycm_server_use_vim_stdout =
|
||||||
|
\ get( g:, 'ycm_server_use_vim_stdout', 0 )
|
||||||
|
|
||||||
|
let g:ycm_server_log_level =
|
||||||
|
\ get( g:, 'ycm_server_log_level', 'info' )
|
||||||
|
|
||||||
" On-demand loading. Let's use the autoload folder and not slow down vim's
|
" On-demand loading. Let's use the autoload folder and not slow down vim's
|
||||||
" startup procedure.
|
" startup procedure.
|
||||||
augroup youcompletemeStart
|
augroup youcompletemeStart
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import threading
|
||||||
|
|
||||||
# We want to have the YouCompleteMe/python directory on the Python PATH because
|
# We want to have the YouCompleteMe/python directory on the Python PATH because
|
||||||
# all the code already assumes that it's there. This is a relic from before the
|
# all the code already assumes that it's there. This is a relic from before the
|
||||||
@ -38,6 +39,7 @@ from bottle import run, request, response
|
|||||||
import server_state
|
import server_state
|
||||||
from ycm import extra_conf_store
|
from ycm import extra_conf_store
|
||||||
from ycm import user_options_store
|
from ycm import user_options_store
|
||||||
|
from ycm import utils
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
# num bytes for the request body buffer; request.json only works if the request
|
# num bytes for the request body buffer; request.json only works if the request
|
||||||
@ -66,10 +68,15 @@ def EventNotification():
|
|||||||
getattr( SERVER_STATE.GetFiletypeCompleter( filetypes ),
|
getattr( SERVER_STATE.GetFiletypeCompleter( filetypes ),
|
||||||
event_handler )( request_data )
|
event_handler )( request_data )
|
||||||
|
|
||||||
|
try:
|
||||||
if hasattr( extra_conf_store, event_handler ):
|
if hasattr( extra_conf_store, event_handler ):
|
||||||
getattr( extra_conf_store, event_handler )( request_data )
|
getattr( extra_conf_store, event_handler )( request_data )
|
||||||
|
except OSError as e:
|
||||||
|
LOGGER.exception( e )
|
||||||
|
|
||||||
|
if event_name == 'VimLeave':
|
||||||
|
_ScheduleServerShutdown()
|
||||||
|
|
||||||
# TODO: shut down the server on VimClose
|
|
||||||
|
|
||||||
|
|
||||||
@app.post( '/run_completer_command' )
|
@app.post( '/run_completer_command' )
|
||||||
@ -140,6 +147,19 @@ def _JsonResponse( data ):
|
|||||||
return json.dumps( data )
|
return json.dumps( data )
|
||||||
|
|
||||||
|
|
||||||
|
def _ScheduleServerShutdown():
|
||||||
|
# The reason why we want to schedule a shutdown in the near future instead of
|
||||||
|
# just shutting down right now is because we want the current request (the one
|
||||||
|
# that made us want to shutdown) to complete successfully first.
|
||||||
|
|
||||||
|
def Shutdown():
|
||||||
|
# sys.exit() doesn't work because we're not in the main thread.
|
||||||
|
utils.TerminateProcess( os.getpid() )
|
||||||
|
|
||||||
|
killer_thread = threading.Timer( 2, Shutdown )
|
||||||
|
killer_thread.start()
|
||||||
|
|
||||||
|
|
||||||
def Main():
|
def Main():
|
||||||
global LOGGER
|
global LOGGER
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
|
|
||||||
def IsIdentifierChar( char ):
|
def IsIdentifierChar( char ):
|
||||||
return char.isalnum() or char == '_'
|
return char.isalnum() or char == '_'
|
||||||
@ -36,3 +38,17 @@ def ToUtf8IfNeeded( string_or_unicode ):
|
|||||||
|
|
||||||
def PathToTempDir():
|
def PathToTempDir():
|
||||||
return os.path.join( tempfile.gettempdir(), 'ycm_temp' )
|
return os.path.join( tempfile.gettempdir(), 'ycm_temp' )
|
||||||
|
|
||||||
|
|
||||||
|
# From here: http://stackoverflow.com/a/8536476/1672783
|
||||||
|
def TerminateProcess( pid ):
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
import ctypes
|
||||||
|
PROCESS_TERMINATE = 1
|
||||||
|
handle = ctypes.windll.kernel32.OpenProcess( PROCESS_TERMINATE,
|
||||||
|
False,
|
||||||
|
pid )
|
||||||
|
ctypes.windll.kernel32.TerminateProcess( handle, -1 )
|
||||||
|
ctypes.windll.kernel32.CloseHandle( handle )
|
||||||
|
else:
|
||||||
|
os.kill( pid, signal.SIGTERM )
|
||||||
|
@ -37,26 +37,39 @@ class YouCompleteMe( object ):
|
|||||||
self._user_options = user_options
|
self._user_options = user_options
|
||||||
self._omnicomp = OmniCompleter( user_options )
|
self._omnicomp = OmniCompleter( user_options )
|
||||||
self._current_completion_request = None
|
self._current_completion_request = None
|
||||||
|
self._server_stdout = None
|
||||||
|
self._server_stderr = None
|
||||||
|
self._SetupServer()
|
||||||
|
|
||||||
|
|
||||||
|
def _SetupServer( self ):
|
||||||
server_port = SERVER_PORT_RANGE_START + os.getpid()
|
server_port = SERVER_PORT_RANGE_START + os.getpid()
|
||||||
command = ''.join( [ 'python ',
|
command = ''.join( [ 'python ',
|
||||||
_PathToServerScript(),
|
_PathToServerScript(),
|
||||||
' --port=',
|
' --port=',
|
||||||
str( server_port ) ] )
|
str( server_port ),
|
||||||
|
' --log=',
|
||||||
|
self._user_options[ 'server_log_level' ] ] )
|
||||||
|
|
||||||
BaseRequest.server_location = 'http://localhost:' + str( server_port )
|
BaseRequest.server_location = 'http://localhost:' + str( server_port )
|
||||||
|
|
||||||
|
if self._user_options[ 'server_use_vim_stdout' ]:
|
||||||
|
subprocess.Popen( command, shell = True )
|
||||||
|
else:
|
||||||
filename_format = os.path.join( utils.PathToTempDir(),
|
filename_format = os.path.join( utils.PathToTempDir(),
|
||||||
'server_{port}_{std}.log' )
|
'server_{port}_{std}.log' )
|
||||||
|
|
||||||
self._server_stdout = filename_format.format( port=server_port,
|
self._server_stdout = filename_format.format( port = server_port,
|
||||||
std='stdout' )
|
std = 'stdout' )
|
||||||
self._server_stderr = filename_format.format( port=server_port,
|
self._server_stderr = filename_format.format( port = server_port,
|
||||||
std='stderr' )
|
std = 'stderr' )
|
||||||
|
|
||||||
with open( self._server_stderr, 'w' ) as fstderr:
|
with open( self._server_stderr, 'w' ) as fstderr:
|
||||||
with open( self._server_stdout, 'w' ) as fstdout:
|
with open( self._server_stdout, 'w' ) as fstdout:
|
||||||
subprocess.Popen( command, stdout=fstdout, stderr=fstderr, shell=True )
|
subprocess.Popen( command,
|
||||||
|
stdout = fstdout,
|
||||||
|
stderr = fstderr,
|
||||||
|
shell = True )
|
||||||
|
|
||||||
|
|
||||||
def CreateCompletionRequest( self ):
|
def CreateCompletionRequest( self ):
|
||||||
|
Loading…
Reference in New Issue
Block a user