Skip to content

Commit 9f208a6

Browse files
Improve terminals (#413)
1 parent 0e35a05 commit 9f208a6

File tree

2 files changed

+44
-21
lines changed

2 files changed

+44
-21
lines changed

plugins/terminals/fps_terminals/routes.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ async def create_terminal(
2626
self,
2727
user: User,
2828
):
29-
name = str(len(TERMINALS) + 1)
29+
name_int = 1
30+
while True:
31+
if str(name_int) not in TERMINALS:
32+
break
33+
name_int += 1
34+
name = str(name_int)
3035
terminal = Terminal(
3136
name=name,
3237
last_activity=datetime.utcnow().isoformat() + "Z",

plugins/terminals/fps_terminals/server.py

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,28 @@ def __init__(self):
3030
async def serve(self, websocket, permissions):
3131
self.websocket = websocket
3232
self.websockets.append(websocket)
33-
self.event = asyncio.Event()
33+
self.data_from_terminal = asyncio.Queue()
3434
self.loop = asyncio.get_event_loop()
3535

36-
task = asyncio.create_task(self.send_data())
36+
task = asyncio.create_task(self.send_data()) # noqa: F841
3737

3838
def on_output():
3939
try:
40-
self.data_or_disconnect = self.p_out.read(65536).decode()
41-
self.event.set()
42-
except Exception:
43-
os.close(self.fd)
44-
self.loop.remove_reader(self.p_out)
45-
self.data_or_disconnect = None
46-
self.event.set()
40+
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
50+
self.data_from_terminal.put_nowait(None)
51+
self.websockets.clear()
52+
self.quit()
53+
else:
54+
self.data_from_terminal.put_nowait(data)
4755

4856
self.loop.add_reader(self.p_out, on_output)
4957
await websocket.send_json(["setup", {}])
@@ -58,21 +66,31 @@ def on_output():
5866
winsize = struct.pack("HH", msg[1], msg[2])
5967
fcntl.ioctl(self.fd, termios.TIOCSWINSZ, winsize)
6068
except WebSocketDisconnect:
61-
task.cancel()
69+
self.quit(websocket)
6270

6371
async def send_data(self):
6472
while True:
65-
await self.event.wait()
66-
self.event.clear()
67-
if self.data_or_disconnect is None:
68-
await self.websocket.send_json(["disconnect", 1])
69-
else:
70-
for websocket in self.websockets:
71-
await websocket.send_json(["stdout", self.data_or_disconnect])
73+
data = await self.data_from_terminal.get()
74+
if data is None:
75+
try:
76+
await self.websocket.send_json(["disconnect", 1])
77+
except Exception:
78+
pass
79+
return
80+
81+
for websocket in self.websockets:
82+
await websocket.send_json(["stdout", data])
7283

73-
def quit(self, websocket):
84+
def quit(self, websocket=None):
7485
if websocket in self.websockets:
7586
self.websockets.remove(websocket)
7687
if not self.websockets:
77-
os.close(self.fd)
78-
self.loop.remove_reader(self.p_out)
88+
try:
89+
self.loop.remove_reader(self.p_out)
90+
except Exception:
91+
pass
92+
try:
93+
os.close(self.fd)
94+
except OSError:
95+
pass
96+
self.data_from_terminal.put_nowait(None)

0 commit comments

Comments
 (0)