1
1
"""Manager for jupyter server proxy"""
2
2
3
- from collections import namedtuple
4
-
5
- from jupyter_server .utils import url_path_join as ujoin
6
- from tornado .ioloop import PeriodicCallback
7
-
8
- from .utils import check_pid
9
-
10
- ServerProxy = namedtuple ("ServerProxy" , ["name" , "url" , "cmd" , "port" , "managed" ])
11
- ServerProxyProc = namedtuple ("ServerProxyProc" , ["name" , "proc" ])
3
+ import asyncio
12
4
5
+ from collections import namedtuple
13
6
14
- async def monitor_server_proxy_procs ():
15
- """Perodically monitor the server proxy processes. If user terminates
16
- the process outside of jupyter-server-proxy, we should be able to
17
- capture that and remove proxy app from manager"""
18
- # Get current active apps
19
- procs = manager ._list_server_proxy_procs ()
7
+ from traitlets import List , Int
8
+ from traitlets .config import LoggingConfigurable
20
9
21
- # Check if all pids are alive
22
- for proc in procs :
23
- exists = check_pid (proc .proc .pid )
24
- if not exists :
25
- await manager .del_server_proxy_app (proc .name )
10
+ from jupyter_server .utils import url_path_join as ujoin
26
11
27
12
28
- class ServerProxyAppManager :
13
+ ServerProxy = namedtuple (
14
+ "ServerProxy" ,
15
+ [
16
+ "name" ,
17
+ "url" ,
18
+ "cmd" ,
19
+ "port" ,
20
+ "managed" ,
21
+ "unix_socket"
22
+ ],
23
+ defaults = ["" ] * 6
24
+ )
25
+ ServerProxyProc = namedtuple (
26
+ "ServerProxyProc" ,
27
+ [
28
+ "name" ,
29
+ "proc"
30
+ ],
31
+ defaults = ["" ] * 2
32
+ )
33
+
34
+
35
+ class ServerProxyAppManager (LoggingConfigurable ):
29
36
"""
30
37
A class for listing and stopping server proxies that are started
31
38
by jupyter server proxy.
32
39
"""
33
40
34
- def __init__ (self ):
35
- """Initialize the server proxy manager"""
36
- # List of server proxy apps
37
- self .server_proxy_apps = []
41
+ server_proxy_apps = List (
42
+ help = "List of server proxy apps"
43
+ )
38
44
39
- # List of server proxy app proc objects. For internal use only
40
- self ._server_proxy_procs = []
45
+ _server_proxy_procs = List (
46
+ help = "List of server proxy app proc objects"
47
+ )
41
48
42
- # Total number of currently running proxy apps
43
- self .num_active_server_proxy_apps = 0
49
+ num_active_server_proxy_apps = Int (
50
+ 0 ,
51
+ help = "Total number of currently running proxy apps"
52
+ )
44
53
45
- async def add_server_proxy_app (self , name , base_url , cmd , port , proc ):
54
+ def add_server_proxy_app (self , name , base_url , cmd , port , proc , unix_socket ):
46
55
"""Add a launched proxy server to list"""
47
56
self .num_active_server_proxy_apps += 1
48
57
@@ -54,6 +63,7 @@ async def add_server_proxy_app(self, name, base_url, cmd, port, proc):
54
63
cmd = " " .join (cmd ),
55
64
port = port ,
56
65
managed = True if proc else False ,
66
+ unix_socket = unix_socket if unix_socket is not None else ''
57
67
)
58
68
)
59
69
@@ -65,24 +75,25 @@ async def add_server_proxy_app(self, name, base_url, cmd, port, proc):
65
75
proc = proc ,
66
76
)
67
77
)
78
+ self .log .debug ("Server proxy %s added to server proxy manager" % name )
68
79
69
- async def del_server_proxy_app (self , name ):
80
+ def del_server_proxy_app (self , name ):
70
81
"""Remove a launched proxy server from list"""
71
82
self .server_proxy_apps = [
72
83
app for app in self .server_proxy_apps if app .name != name
73
84
]
74
85
self ._server_proxy_procs = [
75
86
app for app in self ._server_proxy_procs if app .name != name
76
87
]
77
- self .num_active_server_proxy_apps -= 1
88
+ self .num_active_server_proxy_apps = len ( self . server_proxy_apps )
78
89
79
90
def get_server_proxy_app (self , name ):
80
91
"""Get a given server proxy app"""
81
- return next ((app for app in self .server_proxy_apps if app .name == name ), {} )
92
+ return next ((app for app in self .server_proxy_apps if app .name == name ), ServerProxy () )
82
93
83
94
def _get_server_proxy_proc (self , name ):
84
95
"""Get a given server proxy app"""
85
- return next ((app for app in self ._server_proxy_procs if app .name == name ), {} )
96
+ return next ((app for app in self ._server_proxy_procs if app .name == name ), ServerProxyProc () )
86
97
87
98
def list_server_proxy_apps (self ):
88
99
"""List all active server proxy apps"""
@@ -107,21 +118,32 @@ async def terminate_server_proxy_app(self, name):
107
118
await app .proc .terminate ()
108
119
109
120
# Remove proxy app from list
110
- await self .del_server_proxy_app (name )
121
+ self .del_server_proxy_app (name )
122
+
123
+ self .log .debug ("Server proxy %s removed from server proxy manager" % name )
111
124
112
125
return True
113
126
except (KeyError , AttributeError ):
127
+ self .log .warning ("Server proxy %s not found in server proxy manager" % name )
114
128
return None
115
129
116
130
async def terminate_all (self ):
117
131
"""Close all server proxy and cleanup"""
118
132
for app in self .server_proxy_apps :
119
133
await self .terminate_server_proxy_app (app )
120
134
121
-
122
- # Create a default manager to keep track of server proxy apps.
123
- manager = ServerProxyAppManager ()
124
-
125
- # Create a Periodic call back function to check the status of processes
126
- pc = PeriodicCallback (monitor_server_proxy_procs , 1e4 )
127
- pc .start ()
135
+ async def monitor (self , monitor_interval ):
136
+ while True :
137
+ procs = self ._list_server_proxy_procs ()
138
+
139
+ # Check if processes are running
140
+ for proc in procs :
141
+ running = proc .proc .running
142
+ if not running :
143
+ self .log .warning (
144
+ "Server proxy %s is not running anymore. "
145
+ "Removing from server proxy manager" % proc .name
146
+ )
147
+ self .del_server_proxy_app (proc .name )
148
+
149
+ await asyncio .sleep (monitor_interval )
0 commit comments