|
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