Removed communicate call. Moved log file handling to the server daemon

This commit is contained in:
unknown 2014-03-02 00:14:14 -06:00
parent a4e28157c4
commit 404c167525
2 changed files with 46 additions and 23 deletions

View File

@ -26,6 +26,7 @@ import json
import argparse import argparse
import waitress import waitress
import signal import signal
import os
from ycm import user_options_store from ycm import user_options_store
from ycm import extra_conf_store from ycm import extra_conf_store
from ycm.server.watchdog_plugin import WatchdogPlugin from ycm.server.watchdog_plugin import WatchdogPlugin
@ -38,8 +39,25 @@ def YcmCoreSanityCheck():
# We manually call sys.exit() on SIGTERM and SIGINT so that atexit handlers are # We manually call sys.exit() on SIGTERM and SIGINT so that atexit handlers are
# properly executed. # properly executed.
def SetUpSignalHandler(): def SetUpSignalHandler(stdout, stderr, keep_logfiles):
def SignalHandler( signum, frame ): def SignalHandler( signum, frame ):
if stderr:
# Reset stderr, just in case something tries to use it
tmp = sys.stderr
sys.stderr = sys.__stderr__
tmp.close()
if stdout:
# Reset stdout, just in case something tries to use it
tmp = sys.stdout
sys.stdout = sys.__stdout__
tmp.close()
if not keep_logfiles:
if stderr:
utils.RemoveIfExists( stderr )
if stdout:
utils.RemoveIfExists( stdout )
sys.exit() sys.exit()
for sig in [ signal.SIGTERM, for sig in [ signal.SIGTERM,
@ -61,8 +79,21 @@ def Main():
help = 'num idle seconds before server shuts down') help = 'num idle seconds before server shuts down')
parser.add_argument( '--options_file', type = str, default = '', parser.add_argument( '--options_file', type = str, default = '',
help = 'file with user options, in JSON format' ) help = 'file with user options, in JSON format' )
parser.add_argument( '--stdout', type = str, default = None,
help = 'optional file to use for stdout' )
parser.add_argument( '--stderr', type = str, default = None,
help = 'optional file to use for stderr' )
parser.add_argument( '--keep_logfiles', action = 'store_true', default = None,
help = 'optional file to use for stderr' )
args = parser.parse_args() args = parser.parse_args()
if args.stdout is not None:
sys.stdout = open(args.stdout, "wb")
#os.dup2(stdout.fileno(), sys.stdout.fileno())
if args.stderr is not None:
sys.stderr = open(args.stderr, "wb")
#os.dup2(stderr.fileno(), sys.stderr.fileno())
numeric_level = getattr( logging, args.log.upper(), None ) numeric_level = getattr( logging, args.log.upper(), None )
if not isinstance( numeric_level, int ): if not isinstance( numeric_level, int ):
raise ValueError( 'Invalid log level: %s' % args.log ) raise ValueError( 'Invalid log level: %s' % args.log )
@ -86,7 +117,7 @@ def Main():
# preload has executed. # preload has executed.
from ycm.server import handlers from ycm.server import handlers
handlers.UpdateUserOptions( options ) handlers.UpdateUserOptions( options )
SetUpSignalHandler() SetUpSignalHandler(args.stdout, args.stderr, args.keep_logfiles)
handlers.app.install( WatchdogPlugin( args.idle_suicide_seconds ) ) handlers.app.install( WatchdogPlugin( args.idle_suicide_seconds ) )
waitress.serve( handlers.app, waitress.serve( handlers.app,
host = args.host, host = args.host,

View File

@ -22,6 +22,7 @@ import vim
import tempfile import tempfile
import json import json
import signal import signal
from subprocess import PIPE
from ycm import vimsupport from ycm import vimsupport
from ycm import utils from ycm import utils
from ycm.diagnostic_interface import DiagnosticInterface from ycm.diagnostic_interface import DiagnosticInterface
@ -84,26 +85,22 @@ class YouCompleteMe( object ):
self._SetupServer() self._SetupServer()
self._ycmd_keepalive.Start() self._ycmd_keepalive.Start()
def _SetupServer( self ): def _SetupServer( self ):
server_port = utils.GetUnusedLocalhostPort() server_port = utils.GetUnusedLocalhostPort()
with tempfile.NamedTemporaryFile( delete = False ) as options_file: with tempfile.NamedTemporaryFile( delete = False ) as options_file:
self._temp_options_filename = options_file.name self._temp_options_filename = options_file.name
json.dump( dict( self._user_options ), options_file ) json.dump( dict( self._user_options ), options_file )
options_file.flush() options_file.flush()
args = [ utils.PathToPythonInterpreter(), args = [ utils.PathToPythonInterpreter(),
_PathToServerScript(), _PathToServerScript(),
'--port={0}'.format( server_port ), '--port={0}'.format( server_port ),
'--options_file={0}'.format( options_file.name ), '--options_file={0}'.format( options_file.name ),
'--log={0}'.format( self._user_options[ 'server_log_level' ] ), '--log={0}'.format( self._user_options[ 'server_log_level' ] ),
'--idle_suicide_seconds={0}'.format( '--idle_suicide_seconds={0}'.format(
SERVER_IDLE_SUICIDE_SECONDS ) ] SERVER_IDLE_SUICIDE_SECONDS )]
BaseRequest.server_location = 'http://localhost:' + str( server_port ) if not self._user_options[ 'server_use_vim_stdout' ]:
if self._user_options[ 'server_use_vim_stdout' ]:
self._server_popen = utils.SafePopen( args )
else:
filename_format = os.path.join( utils.PathToTempDir(), filename_format = os.path.join( utils.PathToTempDir(),
'server_{port}_{std}.log' ) 'server_{port}_{std}.log' )
@ -111,15 +108,18 @@ class YouCompleteMe( object ):
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' )
args.append('--stdout={0}'.format( self._server_stdout ))
args.append('--stderr={0}'.format( self._server_stderr ))
if self._user_options[ 'server_keep_logfiles' ]:
args.append('--keep_logfiles')
self._server_popen = utils.SafePopen( args, stdout = PIPE, stderr = PIPE)
BaseRequest.server_location = 'http://localhost:' + str( server_port )
with open( self._server_stderr, 'w' ) as fstderr:
with open( self._server_stdout, 'w' ) as fstdout:
self._server_popen = utils.SafePopen( args,
stdout = fstdout,
stderr = fstderr )
self._NotifyUserIfServerCrashed() self._NotifyUserIfServerCrashed()
def _IsServerAlive( self ): def _IsServerAlive( self ):
returncode = self._server_popen.poll() returncode = self._server_popen.poll()
# When the process hasn't finished yet, poll() returns None. # When the process hasn't finished yet, poll() returns None.
@ -149,16 +149,8 @@ class YouCompleteMe( object ):
def _ServerCleanup( self ): def _ServerCleanup( self ):
if self._IsServerAlive(): if self._IsServerAlive():
self._server_popen.terminate() self._server_popen.terminate()
self._server_popen.communicate()
utils.RemoveIfExists( self._temp_options_filename ) utils.RemoveIfExists( self._temp_options_filename )
if not self._user_options[ 'server_keep_logfiles' ]:
if self._server_stderr:
utils.RemoveIfExists( self._server_stderr )
if self._server_stdout:
utils.RemoveIfExists( self._server_stdout )
def RestartServer( self ): def RestartServer( self ):
vimsupport.PostVimMessage( 'Restarting ycmd server...' ) vimsupport.PostVimMessage( 'Restarting ycmd server...' )
self._user_notified_about_crash = False self._user_notified_about_crash = False