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:
MinRK
2014-10-14 14:39:53 -07:00
parent 2991468a32
commit 08fd76d1e8
2 changed files with 38 additions and 6 deletions

View File

@@ -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

View File

@@ -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