mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-16 22:43:00 +00:00
wait for HTTP servers to start accepting requests
avoids error messages in the proxy when servers are slow to start.
This commit is contained in:
@@ -26,7 +26,7 @@ from sqlalchemy import create_engine
|
||||
|
||||
from IPython.utils.py3compat import str_to_unicode
|
||||
|
||||
from .utils import random_port, url_path_join, wait_for_server
|
||||
from .utils import random_port, url_path_join, wait_for_server, wait_for_http_server
|
||||
|
||||
|
||||
def new_token(*args, **kwargs):
|
||||
@@ -96,9 +96,12 @@ class Server(Base):
|
||||
)
|
||||
|
||||
@gen.coroutine
|
||||
def wait_up(self, timeout=10):
|
||||
def wait_up(self, timeout=10, http=False):
|
||||
"""Wait for this server to come up"""
|
||||
yield wait_for_server(self.ip or 'localhost', self.port, timeout=timeout)
|
||||
if http:
|
||||
yield wait_for_http_server(self.url.replace('//*', '//localhost'), timeout=timeout)
|
||||
else:
|
||||
yield wait_for_server(self.ip or 'localhost', self.port, timeout=timeout)
|
||||
|
||||
def is_up(self):
|
||||
"""Is the server accepting connections?"""
|
||||
@@ -323,8 +326,8 @@ class User(Base):
|
||||
self.state = spawner.get_state()
|
||||
self.last_activity = datetime.utcnow()
|
||||
db.commit()
|
||||
|
||||
yield self.server.wait_up()
|
||||
|
||||
yield self.server.wait_up(http=True)
|
||||
raise gen.Return(self)
|
||||
|
||||
@gen.coroutine
|
||||
|
@@ -8,6 +8,7 @@ import errno
|
||||
import os
|
||||
import socket
|
||||
from tornado import web, gen, ioloop
|
||||
from tornado.httpclient import HTTPRequest, AsyncHTTPClient, HTTPError
|
||||
from tornado.log import app_log
|
||||
|
||||
from IPython.html.utils import url_path_join
|
||||
@@ -41,7 +42,7 @@ def random_hex(nbytes):
|
||||
|
||||
@gen.coroutine
|
||||
def wait_for_server(ip, port, timeout=10):
|
||||
"""wait for a server to show up at ip:port"""
|
||||
"""wait for any server to show up at ip:port"""
|
||||
loop = ioloop.IOLoop.current()
|
||||
tic = loop.time()
|
||||
while loop.time() - tic < timeout:
|
||||
@@ -57,6 +58,34 @@ def wait_for_server(ip, port, timeout=10):
|
||||
return
|
||||
raise TimeoutError
|
||||
|
||||
@gen.coroutine
|
||||
def wait_for_http_server(url, timeout=10):
|
||||
"""Wait for an HTTP Server to respond at url
|
||||
|
||||
Any non-5XX response code will do, even 404.
|
||||
"""
|
||||
loop = ioloop.IOLoop.current()
|
||||
tic = loop.time()
|
||||
client = AsyncHTTPClient()
|
||||
while loop.time() - tic < timeout:
|
||||
try:
|
||||
r = yield client.fetch(url, follow_redirects=False)
|
||||
except HTTPError as e:
|
||||
if e.code >= 500:
|
||||
# failed to respond properly, wait and try again
|
||||
if e.code != 599:
|
||||
# we expect 599 for no connection,
|
||||
# but 502 or other proxy error is conceivable
|
||||
app_log.warn("Server at %s responded with error: %s", url, e.code)
|
||||
yield gen.Task(loop.add_timeout, loop.time() + 0.25)
|
||||
else:
|
||||
app_log.debug("Server at %s responded with %s", url, e.code)
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
||||
raise TimeoutError
|
||||
|
||||
def auth_decorator(check_auth):
|
||||
"""Make an authentication decorator
|
||||
|
||||
|
Reference in New Issue
Block a user