|
36 | 36 |
|
37 | 37 | from types import ModuleType
|
38 | 38 | from base64 import encodebytes
|
| 39 | +try: |
| 40 | + import resource |
| 41 | +except ImportError: |
| 42 | + # Windows |
| 43 | + resource = None |
| 44 | + |
39 | 45 | from jinja2 import Environment, FileSystemLoader
|
40 | 46 |
|
41 | 47 | from jupyter_server.transutils import trans, _
|
@@ -758,6 +764,30 @@ def _token_default(self):
|
758 | 764 | self._token_generated = True
|
759 | 765 | return binascii.hexlify(os.urandom(24)).decode('ascii')
|
760 | 766 |
|
| 767 | + min_open_files_limit = Integer(config=True, |
| 768 | + help=""" |
| 769 | + Gets or sets a lower bound on the open file handles process resource |
| 770 | + limit. This may need to be increased if you run into an |
| 771 | + OSError: [Errno 24] Too many open files. |
| 772 | + This is not applicable when running on Windows. |
| 773 | + """) |
| 774 | + |
| 775 | + @default('min_open_files_limit') |
| 776 | + def _default_min_open_files_limit(self): |
| 777 | + if resource is None: |
| 778 | + # Ignoring min_open_files_limit because the limit cannot be adjusted (for example, on Windows) |
| 779 | + return None |
| 780 | + |
| 781 | + soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) |
| 782 | + |
| 783 | + DEFAULT_SOFT = 4096 |
| 784 | + if hard >= DEFAULT_SOFT: |
| 785 | + return DEFAULT_SOFT |
| 786 | + |
| 787 | + self.log.debug("Default value for min_open_files_limit is ignored (hard=%r, soft=%r)", hard, soft) |
| 788 | + |
| 789 | + return soft |
| 790 | + |
761 | 791 | max_body_size = Integer(512 * 1024 * 1024, config=True,
|
762 | 792 | help="""
|
763 | 793 | Sets the maximum allowed size of the client request body, specified in
|
@@ -1395,6 +1425,23 @@ def init_webapp(self):
|
1395 | 1425 |
|
1396 | 1426 | self.login_handler_class.validate_security(self, ssl_options=self.ssl_options)
|
1397 | 1427 |
|
| 1428 | + def init_resources(self): |
| 1429 | + """initialize system resources""" |
| 1430 | + if resource is None: |
| 1431 | + self.log.debug('Ignoring min_open_files_limit because the limit cannot be adjusted (for example, on Windows)') |
| 1432 | + return |
| 1433 | + |
| 1434 | + old_soft, old_hard = resource.getrlimit(resource.RLIMIT_NOFILE) |
| 1435 | + soft = self.min_open_files_limit |
| 1436 | + hard = old_hard |
| 1437 | + if old_soft < soft: |
| 1438 | + if hard < soft: |
| 1439 | + hard = soft |
| 1440 | + self.log.debug( |
| 1441 | + 'Raising open file limit: soft {}->{}; hard {}->{}'.format(old_soft, soft, old_hard, hard) |
| 1442 | + ) |
| 1443 | + resource.setrlimit(resource.RLIMIT_NOFILE, (soft, hard)) |
| 1444 | + |
1398 | 1445 | @property
|
1399 | 1446 | def display_url(self):
|
1400 | 1447 | if self.custom_display_url:
|
@@ -1712,6 +1759,7 @@ def initialize(self, argv=None, find_extensions=True, new_httpserver=True):
|
1712 | 1759 | self.find_server_extensions()
|
1713 | 1760 | self.init_logging()
|
1714 | 1761 | self.init_server_extensions()
|
| 1762 | + self.init_resources() |
1715 | 1763 | self.init_configurables()
|
1716 | 1764 | self.init_components()
|
1717 | 1765 | self.init_webapp()
|
|
0 commit comments