Skip to content

Commit 7de8df4

Browse files
authored
Gateway only: Ensure launch and request timeouts are in sync (#5317)
Prior to this change, the request timeout for a Gateway request was synchronized with KERNEL_LAUNCH_TIMEOUT only if KLT was greater. However, the two are closely associated and KLT should be adjusted if the configurable request_timeout is greater. This change ensures that the two values are synchronized to the greater value. It changes the two configurable timeouts to default to 40 (to match that of KLT) and removes the 2-second pad, since that wasn't helpful and only confused the situation. These changes were prompted by this issue: jupyter-server/enterprise_gateway#792
1 parent beeac48 commit 7de8df4

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

notebook/gateway/managers.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _kernelspecs_endpoint_default(self):
102102
def _kernelspecs_resource_endpoint_default(self):
103103
return os.environ.get(self.kernelspecs_resource_endpoint_env, self.kernelspecs_resource_endpoint_default_value)
104104

105-
connect_timeout_default_value = 60.0
105+
connect_timeout_default_value = 40.0
106106
connect_timeout_env = 'JUPYTER_GATEWAY_CONNECT_TIMEOUT'
107107
connect_timeout = Float(default_value=connect_timeout_default_value, config=True,
108108
help="""The time allowed for HTTP connection establishment with the Gateway server.
@@ -112,7 +112,7 @@ def _kernelspecs_resource_endpoint_default(self):
112112
def connect_timeout_default(self):
113113
return float(os.environ.get('JUPYTER_GATEWAY_CONNECT_TIMEOUT', self.connect_timeout_default_value))
114114

115-
request_timeout_default_value = 60.0
115+
request_timeout_default_value = 40.0
116116
request_timeout_env = 'JUPYTER_GATEWAY_REQUEST_TIMEOUT'
117117
request_timeout = Float(default_value=request_timeout_default_value, config=True,
118118
help="""The time allowed for HTTP request completion. (JUPYTER_GATEWAY_REQUEST_TIMEOUT env var)""")
@@ -226,18 +226,20 @@ def gateway_enabled(self):
226226

227227
# Ensure KERNEL_LAUNCH_TIMEOUT has a default value.
228228
KERNEL_LAUNCH_TIMEOUT = int(os.environ.get('KERNEL_LAUNCH_TIMEOUT', 40))
229-
os.environ['KERNEL_LAUNCH_TIMEOUT'] = str(KERNEL_LAUNCH_TIMEOUT)
230-
231-
LAUNCH_TIMEOUT_PAD = int(os.environ.get('LAUNCH_TIMEOUT_PAD', 2))
232229

233230
def init_static_args(self):
234231
"""Initialize arguments used on every request. Since these are static values, we'll
235232
perform this operation once.
236233
237234
"""
238-
# Ensure that request timeout is at least "pad" greater than launch timeout.
239-
if self.request_timeout < float(GatewayClient.KERNEL_LAUNCH_TIMEOUT + GatewayClient.LAUNCH_TIMEOUT_PAD):
240-
self.request_timeout = float(GatewayClient.KERNEL_LAUNCH_TIMEOUT + GatewayClient.LAUNCH_TIMEOUT_PAD)
235+
# Ensure that request timeout and KERNEL_LAUNCH_TIMEOUT are the same, taking the
236+
# greater value of the two.
237+
if self.request_timeout < float(GatewayClient.KERNEL_LAUNCH_TIMEOUT):
238+
self.request_timeout = float(GatewayClient.KERNEL_LAUNCH_TIMEOUT)
239+
elif self.request_timeout > float(GatewayClient.KERNEL_LAUNCH_TIMEOUT):
240+
GatewayClient.KERNEL_LAUNCH_TIMEOUT = int(self.request_timeout)
241+
# Ensure any adjustments are reflected in env.
242+
os.environ['KERNEL_LAUNCH_TIMEOUT'] = str(GatewayClient.KERNEL_LAUNCH_TIMEOUT)
241243

242244
self._static_args['headers'] = json.loads(self.headers)
243245
if 'Authorization' not in self._static_args['headers'].keys():

notebook/tests/test_gateway.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ def mock_gateway_request(url, **kwargs):
117117
raise gen.Return(response)
118118

119119
# Fetch existing kernel
120-
if endpoint.rfind('/api/kernels/') >= 0 and method == 'GET':
121-
requested_kernel_id = endpoint.rpartition('/')[2]
120+
if endpoint.rfind('/api/kernels/') >= 0 and method == 'GET':
121+
requested_kernel_id = endpoint.rpartition('/')[2]
122122
if requested_kernel_id in running_kernels:
123123
response_buf = StringIO(json.dumps(running_kernels.get(requested_kernel_id)))
124124
response = yield maybe_future(HTTPResponse(request, 200, buffer=response_buf))
@@ -149,21 +149,28 @@ def teardown_class(cls):
149149
def get_patch_env(cls):
150150
test_env = super(TestGateway, cls).get_patch_env()
151151
test_env.update({'JUPYTER_GATEWAY_URL': TestGateway.mock_gateway_url,
152-
'JUPYTER_GATEWAY_REQUEST_TIMEOUT': '44.4'})
152+
'JUPYTER_GATEWAY_CONNECT_TIMEOUT': '44.4'})
153153
return test_env
154154

155155
@classmethod
156156
def get_argv(cls):
157157
argv = super(TestGateway, cls).get_argv()
158-
argv.extend(['--GatewayClient.connect_timeout=44.4', '--GatewayClient.http_user=' + TestGateway.mock_http_user])
158+
argv.extend(['--GatewayClient.request_timeout=96.0', '--GatewayClient.http_user=' + TestGateway.mock_http_user])
159159
return argv
160160

161+
def setUp(self):
162+
kwargs = dict()
163+
GatewayClient.instance().load_connection_args(**kwargs)
164+
super(TestGateway, self).setUp()
165+
161166
def test_gateway_options(self):
162167
nt.assert_equal(self.notebook.gateway_config.gateway_enabled, True)
163168
nt.assert_equal(self.notebook.gateway_config.url, TestGateway.mock_gateway_url)
164169
nt.assert_equal(self.notebook.gateway_config.http_user, TestGateway.mock_http_user)
165170
nt.assert_equal(self.notebook.gateway_config.connect_timeout, self.notebook.gateway_config.connect_timeout)
166171
nt.assert_equal(self.notebook.gateway_config.connect_timeout, 44.4)
172+
nt.assert_equal(self.notebook.gateway_config.request_timeout, 96.0)
173+
nt.assert_equal(os.environ['KERNEL_LAUNCH_TIMEOUT'], str(96)) # Ensure KLT gets set from request-timeout
167174

168175
def test_gateway_class_mappings(self):
169176
# Ensure appropriate class mappings are in place.

0 commit comments

Comments
 (0)