6
6
import struct
7
7
import termios
8
8
9
- from fastapi import WebSocketDisconnect
10
-
11
9
from jupyverse_api .terminals import TerminalServer
12
10
13
11
@@ -25,35 +23,26 @@ class _TerminalServer(TerminalServer):
25
23
def __init__ (self ):
26
24
self .fd = open_terminal ()
27
25
self .p_out = os .fdopen (self .fd , "w+b" , 0 )
28
- self .websockets = []
29
-
30
- async def serve (self , websocket , permissions ):
31
- self .websocket = websocket
32
- self .websockets .append (websocket )
33
- self .data_from_terminal = asyncio .Queue ()
34
26
self .loop = asyncio .get_event_loop ()
35
-
36
- task = asyncio . create_task ( self .send_data ()) # noqa: F841
27
+ self . data_from_terminal = asyncio . Queue ()
28
+ self .websockets = []
37
29
38
30
def on_output ():
39
31
try :
40
32
data = self .p_out .read (65536 ).decode ()
41
- except OSError :
42
- try :
43
- self .loop .remove_reader (self .p_out )
44
- except Exception :
45
- pass
46
- try :
47
- os .close (self .fd )
48
- except OSError :
49
- pass
33
+ except Exception :
50
34
self .data_from_terminal .put_nowait (None )
51
- self .websockets .clear ()
52
- self .quit ()
53
35
else :
54
36
self .data_from_terminal .put_nowait (data )
55
37
56
38
self .loop .add_reader (self .p_out , on_output )
39
+
40
+ async def serve (self , websocket , permissions , terminals , name ):
41
+ self .websocket = websocket
42
+ self .websockets .append (websocket )
43
+
44
+ task = asyncio .create_task (self .send_data (terminals , name )) # noqa: F841
45
+
57
46
await websocket .send_json (["setup" , {}])
58
47
can_execute = permissions is None or "execute" in permissions .get ("terminals" , [])
59
48
try :
@@ -65,32 +54,29 @@ def on_output():
65
54
elif msg [0 ] == "set_size" :
66
55
winsize = struct .pack ("HH" , msg [1 ], msg [2 ])
67
56
fcntl .ioctl (self .fd , termios .TIOCSWINSZ , winsize )
68
- except WebSocketDisconnect :
69
- self .quit (websocket )
57
+ except Exception :
58
+ if websocket in self .websockets :
59
+ self .websockets .remove (websocket )
70
60
71
- async def send_data (self ):
61
+ async def send_data (self , terminals , name ):
72
62
while True :
73
63
data = await self .data_from_terminal .get ()
74
64
if data is None :
75
- try :
76
- await self .websocket .send_json (["disconnect" , 1 ])
77
- except Exception :
78
- pass
65
+ await self .exit (terminals , name )
79
66
return
80
67
81
68
for websocket in self .websockets :
82
69
await websocket .send_json (["stdout" , data ])
83
70
84
- def quit (self , websocket = None ):
85
- if websocket in self .websockets :
86
- self .websockets .remove (websocket )
87
- if not self .websockets :
71
+ async def exit (self , terminals , name ):
72
+ for websocket in self .websockets :
88
73
try :
89
- self . loop . remove_reader ( self . p_out )
74
+ await websocket . send_json ([ "disconnect" , 1 ] )
90
75
except Exception :
91
76
pass
92
- try :
93
- os .close (self .fd )
94
- except OSError :
95
- pass
96
- self .data_from_terminal .put_nowait (None )
77
+ self .websockets .clear ()
78
+ try :
79
+ self .loop .remove_reader (self .p_out )
80
+ except Exception :
81
+ pass
82
+ del terminals [name ]
0 commit comments