##// END OF EJS Templates
NotebookApp: Make the number of ports to retry user configurable....
Bradley M. Froehle -
Show More
@@ -20,6 +20,7 b' Authors:'
20 import errno
20 import errno
21 import logging
21 import logging
22 import os
22 import os
23 import random
23 import re
24 import re
24 import select
25 import select
25 import signal
26 import signal
@@ -97,6 +98,17 b' def url_path_join(a,b):'
97 else:
98 else:
98 return a+b
99 return a+b
99
100
101 def random_ports(port, n):
102 """Generate a list of n random ports near the given port.
103
104 The first 5 ports will be sequential, and the remaining n-5 will be
105 randomly selected in the range [port-2*n, port+2*n].
106 """
107 for i in range(min(5, n)):
108 yield port + i
109 for i in range(n-5):
110 yield port + random.randint(-2*n, 2*n)
111
100 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
101 # The Tornado web application
113 # The Tornado web application
102 #-----------------------------------------------------------------------------
114 #-----------------------------------------------------------------------------
@@ -212,6 +224,7 b' aliases = dict(ipkernel_aliases)'
212 aliases.update({
224 aliases.update({
213 'ip': 'NotebookApp.ip',
225 'ip': 'NotebookApp.ip',
214 'port': 'NotebookApp.port',
226 'port': 'NotebookApp.port',
227 'port-retries': 'NotebookApp.port_retries',
215 'keyfile': 'NotebookApp.keyfile',
228 'keyfile': 'NotebookApp.keyfile',
216 'certfile': 'NotebookApp.certfile',
229 'certfile': 'NotebookApp.certfile',
217 'notebook-dir': 'NotebookManager.notebook_dir',
230 'notebook-dir': 'NotebookManager.notebook_dir',
@@ -222,7 +235,7 b' aliases.update({'
222 # multi-kernel evironment:
235 # multi-kernel evironment:
223 aliases.pop('f', None)
236 aliases.pop('f', None)
224
237
225 notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile',
238 notebook_aliases = [u'port', u'port-retries', u'ip', u'keyfile', u'certfile',
226 u'notebook-dir']
239 u'notebook-dir']
227
240
228 #-----------------------------------------------------------------------------
241 #-----------------------------------------------------------------------------
@@ -272,6 +285,9 b' class NotebookApp(BaseIPythonApplication):'
272 port = Integer(8888, config=True,
285 port = Integer(8888, config=True,
273 help="The port the notebook server will listen on."
286 help="The port the notebook server will listen on."
274 )
287 )
288 port_retries = Integer(50, config=True,
289 help="The number of additional ports to try if the specified port is not available."
290 )
275
291
276 certfile = Unicode(u'', config=True,
292 certfile = Unicode(u'', config=True,
277 help="""The full path to an SSL/TLS certificate file."""
293 help="""The full path to an SSL/TLS certificate file."""
@@ -422,10 +438,8 b' class NotebookApp(BaseIPythonApplication):'
422 'but not using any encryption or authentication. This is highly '
438 'but not using any encryption or authentication. This is highly '
423 'insecure and not recommended.')
439 'insecure and not recommended.')
424
440
425 # Try random ports centered around the default.
441 success = None
426 from random import randint
442 for port in random_ports(self.port, self.port_retries+1):
427 n = 50 # Max number of attempts, keep reasonably large.
428 for port in range(self.port, self.port+5) + [self.port + randint(-2*n, 2*n) for i in range(n-5)]:
429 try:
443 try:
430 self.http_server.listen(port, self.ip)
444 self.http_server.listen(port, self.ip)
431 except socket.error, e:
445 except socket.error, e:
@@ -434,7 +448,12 b' class NotebookApp(BaseIPythonApplication):'
434 self.log.info('The port %i is already in use, trying another random port.' % port)
448 self.log.info('The port %i is already in use, trying another random port.' % port)
435 else:
449 else:
436 self.port = port
450 self.port = port
451 success = True
437 break
452 break
453 if not success:
454 self.log.critical('ERROR: the notebook server could not be started because '
455 'no available port could be found.')
456 raise RuntimeError
438
457
439 def init_signal(self):
458 def init_signal(self):
440 # FIXME: remove this check when pyzmq dependency is >= 2.1.11
459 # FIXME: remove this check when pyzmq dependency is >= 2.1.11
General Comments 0
You need to be logged in to leave comments. Login now