Import requests module lazily
The requests module is slow to load so we should import it only when needed to reduce startup time.
This commit is contained in:
parent
39659caf34
commit
09a08d3240
@ -82,7 +82,7 @@ function! youcompleteme#Enable()
|
|||||||
" Note that these events will NOT trigger for the file vim is started with;
|
" Note that these events will NOT trigger for the file vim is started with;
|
||||||
" so if you do "vim foo.cc", these events will not trigger when that buffer
|
" so if you do "vim foo.cc", these events will not trigger when that buffer
|
||||||
" is read. This is because youcompleteme#Enable() is called on VimEnter and
|
" is read. This is because youcompleteme#Enable() is called on VimEnter and
|
||||||
" that happens *after" BufRead/BufEnter has already triggered for the
|
" that happens *after* BufRead/FileType has already triggered for the
|
||||||
" initial file.
|
" initial file.
|
||||||
" We also need to trigger buf init code on the FileType event because when
|
" We also need to trigger buf init code on the FileType event because when
|
||||||
" the user does :enew and then :set ft=something, we need to run buf init
|
" the user does :enew and then :set ft=something, we need to run buf init
|
||||||
@ -97,10 +97,15 @@ function! youcompleteme#Enable()
|
|||||||
autocmd CompleteDone * call s:OnCompleteDone()
|
autocmd CompleteDone * call s:OnCompleteDone()
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" Calling this once solves the problem of BufRead/BufEnter not triggering for
|
" BufRead/FileType events are not triggered for the first loaded file.
|
||||||
" the first loaded file. This should be the last command executed in this
|
" However, we don't directly call the s:OnBufferRead function because it would
|
||||||
" function!
|
" send requests that can't succeed as the server is not ready yet and would
|
||||||
call s:OnBufferRead()
|
" slow down startup.
|
||||||
|
call s:DisableOnLargeFile( expand( '%' ) )
|
||||||
|
|
||||||
|
if s:AllowedToCompleteInCurrentBuffer()
|
||||||
|
call s:SetCompleteFunc()
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,20 +25,16 @@ from builtins import * # noqa
|
|||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
import requests
|
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import json
|
import json
|
||||||
from future.utils import native
|
from future.utils import native
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from requests_futures.sessions import FuturesSession
|
|
||||||
from ycm.unsafe_thread_pool_executor import UnsafeThreadPoolExecutor
|
|
||||||
from ycm import vimsupport
|
from ycm import vimsupport
|
||||||
from ycmd.utils import ToBytes
|
from ycmd.utils import ToBytes
|
||||||
from ycmd.hmac_utils import CreateRequestHmac, CreateHmac, SecureBytesEqual
|
from ycmd.hmac_utils import CreateRequestHmac, CreateHmac, SecureBytesEqual
|
||||||
from ycmd.responses import ServerError, UnknownExtraConf
|
from ycmd.responses import ServerError, UnknownExtraConf
|
||||||
|
|
||||||
_HEADERS = {'content-type': 'application/json'}
|
_HEADERS = {'content-type': 'application/json'}
|
||||||
_EXECUTOR = UnsafeThreadPoolExecutor( max_workers = 30 )
|
|
||||||
_CONNECT_TIMEOUT_SEC = 0.01
|
_CONNECT_TIMEOUT_SEC = 0.01
|
||||||
# Setting this to None seems to screw up the Requests/urllib3 libs.
|
# Setting this to None seems to screw up the Requests/urllib3 libs.
|
||||||
_READ_TIMEOUT_SEC = 30
|
_READ_TIMEOUT_SEC = 30
|
||||||
@ -104,14 +100,14 @@ class BaseRequest( object ):
|
|||||||
request_uri = _BuildUri( handler )
|
request_uri = _BuildUri( handler )
|
||||||
if method == 'POST':
|
if method == 'POST':
|
||||||
sent_data = _ToUtf8Json( data )
|
sent_data = _ToUtf8Json( data )
|
||||||
return BaseRequest.session.post(
|
return BaseRequest.Session().post(
|
||||||
request_uri,
|
request_uri,
|
||||||
data = sent_data,
|
data = sent_data,
|
||||||
headers = BaseRequest._ExtraHeaders( method,
|
headers = BaseRequest._ExtraHeaders( method,
|
||||||
request_uri,
|
request_uri,
|
||||||
sent_data ),
|
sent_data ),
|
||||||
timeout = ( _CONNECT_TIMEOUT_SEC, timeout ) )
|
timeout = ( _CONNECT_TIMEOUT_SEC, timeout ) )
|
||||||
return BaseRequest.session.get(
|
return BaseRequest.Session().get(
|
||||||
request_uri,
|
request_uri,
|
||||||
headers = BaseRequest._ExtraHeaders( method, request_uri ),
|
headers = BaseRequest._ExtraHeaders( method, request_uri ),
|
||||||
timeout = ( _CONNECT_TIMEOUT_SEC, timeout ) )
|
timeout = ( _CONNECT_TIMEOUT_SEC, timeout ) )
|
||||||
@ -129,7 +125,31 @@ class BaseRequest( object ):
|
|||||||
BaseRequest.hmac_secret ) )
|
BaseRequest.hmac_secret ) )
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
session = FuturesSession( executor = _EXECUTOR )
|
|
||||||
|
# These two methods exist to avoid importing the requests module at startup;
|
||||||
|
# reducing loading time since this module is slow to import.
|
||||||
|
@classmethod
|
||||||
|
def Requests( cls ):
|
||||||
|
try:
|
||||||
|
return cls.requests
|
||||||
|
except AttributeError:
|
||||||
|
import requests
|
||||||
|
cls.requests = requests
|
||||||
|
return requests
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def Session( cls ):
|
||||||
|
try:
|
||||||
|
return cls.session
|
||||||
|
except AttributeError:
|
||||||
|
from ycm.unsafe_thread_pool_executor import UnsafeThreadPoolExecutor
|
||||||
|
from requests_futures.sessions import FuturesSession
|
||||||
|
executor = UnsafeThreadPoolExecutor( max_workers = 30 )
|
||||||
|
cls.session = FuturesSession( executor = executor )
|
||||||
|
return cls.session
|
||||||
|
|
||||||
|
|
||||||
server_location = ''
|
server_location = ''
|
||||||
hmac_secret = ''
|
hmac_secret = ''
|
||||||
|
|
||||||
@ -161,7 +181,7 @@ def BuildRequestData( filepath = None ):
|
|||||||
def JsonFromFuture( future ):
|
def JsonFromFuture( future ):
|
||||||
response = future.result()
|
response = future.result()
|
||||||
_ValidateResponseObject( response )
|
_ValidateResponseObject( response )
|
||||||
if response.status_code == requests.codes.server_error:
|
if response.status_code == BaseRequest.Requests().codes.server_error:
|
||||||
raise MakeServerException( response.json() )
|
raise MakeServerException( response.json() )
|
||||||
|
|
||||||
# We let Requests handle the other status types, we only handle the 500
|
# We let Requests handle the other status types, we only handle the 500
|
||||||
@ -199,7 +219,7 @@ def HandleServerException( display = True, truncate = False ):
|
|||||||
_LoadExtraConfFile( e.extra_conf_file )
|
_LoadExtraConfFile( e.extra_conf_file )
|
||||||
else:
|
else:
|
||||||
_IgnoreExtraConfFile( e.extra_conf_file )
|
_IgnoreExtraConfFile( e.extra_conf_file )
|
||||||
except requests.exceptions.ConnectionError:
|
except BaseRequest.Requests().exceptions.ConnectionError:
|
||||||
# We don't display this exception to the user since it is likely to happen
|
# We don't display this exception to the user since it is likely to happen
|
||||||
# for each subsequent request (typically if the server crashed) and we
|
# for each subsequent request (typically if the server crashed) and we
|
||||||
# don't want to spam the user with it.
|
# don't want to spam the user with it.
|
||||||
|
Loading…
Reference in New Issue
Block a user