|
91 | 91 | from .auth.login import LoginHandler |
92 | 92 | from .auth.logout import LogoutHandler |
93 | 93 | from .base.handlers import FileFindHandler |
94 | | -from .terminal import TerminalManager |
95 | 94 |
|
96 | 95 | from traitlets.config import Config |
97 | 96 | from traitlets.config.application import catch_config_error, boolean_flag |
|
132 | 131 | except ImportError: |
133 | 132 | async_kernel_mgmt_available = False |
134 | 133 |
|
| 134 | +# Tolerate missing terminado package. |
| 135 | +try: |
| 136 | + from .terminal import TerminalManager |
| 137 | + terminado_available = True |
| 138 | +except ImportError: |
| 139 | + terminado_available = False |
| 140 | + |
135 | 141 | #----------------------------------------------------------------------------- |
136 | 142 | # Module globals |
137 | 143 | #----------------------------------------------------------------------------- |
@@ -303,7 +309,7 @@ def init_settings(self, jupyter_app, kernel_manager, contents_manager, |
303 | 309 | allow_password_change=jupyter_app.allow_password_change, |
304 | 310 | server_root_dir=root_dir, |
305 | 311 | jinja2_env=env, |
306 | | - terminals_available=False, # Set later if terminals are available |
| 312 | + terminals_available=terminado_available and jupyter_app.terminals_enabled, |
307 | 313 | ) |
308 | 314 |
|
309 | 315 | # allow custom overrides for the tornado web app. |
@@ -673,9 +679,12 @@ class NotebookApp(JupyterApp): |
673 | 679 |
|
674 | 680 | classes = [ |
675 | 681 | KernelManager, Session, MappingKernelManager, KernelSpecManager, |
676 | | - ContentsManager, FileContentsManager, NotebookNotary, TerminalManager, |
| 682 | + ContentsManager, FileContentsManager, NotebookNotary, |
677 | 683 | GatewayKernelManager, GatewayKernelSpecManager, GatewaySessionManager, GatewayClient, |
678 | 684 | ] |
| 685 | + if terminado_available: # Only necessary when terminado is available |
| 686 | + classes.append(TerminalManager) |
| 687 | + |
679 | 688 | flags = Dict(flags) |
680 | 689 | aliases = Dict(aliases) |
681 | 690 |
|
@@ -1486,6 +1495,15 @@ def _update_server_extensions(self, change): |
1486 | 1495 | is not available. |
1487 | 1496 | """)) |
1488 | 1497 |
|
| 1498 | + # Since use of terminals is also a function of whether the terminado package is |
| 1499 | + # available, this variable holds the "final indication" of whether terminal functionality |
| 1500 | + # should be considered (particularly during shutdown/cleanup). It is enabled only |
| 1501 | + # once both the terminals "service" can be initialized and terminals_enabled is True. |
| 1502 | + # Note: this variable is slightly different from 'terminals_available' in the web settings |
| 1503 | + # in that this variable *could* remain false if terminado is available, yet the terminal |
| 1504 | + # service's initialization still fails. As a result, this variable holds the truth. |
| 1505 | + terminals_available = False |
| 1506 | + |
1489 | 1507 | def parse_command_line(self, argv=None): |
1490 | 1508 | super(NotebookApp, self).parse_command_line(argv) |
1491 | 1509 |
|
@@ -1777,7 +1795,7 @@ def init_terminals(self): |
1777 | 1795 | try: |
1778 | 1796 | from .terminal import initialize |
1779 | 1797 | initialize(nb_app=self) |
1780 | | - self.web_app.settings['terminals_available'] = True |
| 1798 | + self.terminals_available = True |
1781 | 1799 | except ImportError as e: |
1782 | 1800 | self.log.warning(_("Terminals not available (error was %s)"), e) |
1783 | 1801 |
|
@@ -1919,18 +1937,14 @@ def init_mime_overrides(self): |
1919 | 1937 | mimetypes.add_type('text/css', '.css') |
1920 | 1938 | mimetypes.add_type('application/javascript', '.js') |
1921 | 1939 |
|
1922 | | - |
1923 | 1940 | def shutdown_no_activity(self): |
1924 | 1941 | """Shutdown server on timeout when there are no kernels or terminals.""" |
1925 | 1942 | km = self.kernel_manager |
1926 | 1943 | if len(km) != 0: |
1927 | 1944 | return # Kernels still running |
1928 | 1945 |
|
1929 | | - try: |
| 1946 | + if self.terminals_available: |
1930 | 1947 | term_mgr = self.web_app.settings['terminal_manager'] |
1931 | | - except KeyError: |
1932 | | - pass # Terminals not enabled |
1933 | | - else: |
1934 | 1948 | if term_mgr.terminals: |
1935 | 1949 | return # Terminals still running |
1936 | 1950 |
|
@@ -2018,11 +2032,10 @@ def cleanup_terminals(self): |
2018 | 2032 | The terminals will shutdown themselves when this process no longer exists, |
2019 | 2033 | but explicit shutdown allows the TerminalManager to cleanup. |
2020 | 2034 | """ |
2021 | | - try: |
2022 | | - terminal_manager = self.web_app.settings['terminal_manager'] |
2023 | | - except KeyError: |
2024 | | - return # Terminals not enabled |
| 2035 | + if not self.terminals_available: |
| 2036 | + return |
2025 | 2037 |
|
| 2038 | + terminal_manager = self.web_app.settings['terminal_manager'] |
2026 | 2039 | n_terminals = len(terminal_manager.list()) |
2027 | 2040 | terminal_msg = trans.ngettext('Shutting down %d terminal', 'Shutting down %d terminals', n_terminals) |
2028 | 2041 | self.log.info(terminal_msg % n_terminals) |
|
0 commit comments