3131
3232from . import sio
3333
34+ server : libtmux .Server | None = None
3435session : Session
3536window : Window
3637pane : Pane
38+ background_emit_task : asyncio .Task | None = None
3739
3840
3941def register_tmux ():
40- global session , window , pane
41- server = libtmux .Server ()
42+ global session , window , pane , server
43+
44+ if server is None :
45+ server = libtmux .Server ()
4246
4347 try :
4448 abs_path_lib = str (get_config ()["gui" ]["terminal" ]["start_path" ].as_str ())
@@ -91,13 +95,13 @@ async def emit_output():
9195 )
9296
9397
94- async def emit_output_continuously (sleep_seconds = 0.01 ):
98+ async def emit_output_continuously (sleep_seconds = 1 ):
9599 # only emit if there was a change
96100 prev : list [str ] = []
97101 prev_x , prev_y = 0 , 0
98102 history : list [str ] = []
99103 while True :
100- await sio .sleep (sleep_seconds ) # type: ignore
104+ await asyncio .sleep (sleep_seconds )
101105 try :
102106 if is_session_alive ():
103107 current = pane .cmd ("capture-pane" , "-p" , "-N" , "-T" , "-e" ).stdout
@@ -182,10 +186,11 @@ async def pty_input(sid, data):
182186 """Write to the child pty."""
183187 # log.debug(f"{sid} input {data}")
184188 pane .send_keys (data ["input" ], enter = False )
185- # await asyncio.gather(
186- # emit_output(),
187- # emit_cursor_position(),
188- # )
189+ # re-emitting continuously at high rate causes quite high cpu load, therefore we
190+ # only re-emit at low intervals, and everytime we _know_ something changed.
191+ await asyncio .gather (
192+ emit_output (),
193+ )
189194
190195
191196@sio .on ("ptyResize" , namespace = "/terminal" )
@@ -209,14 +214,29 @@ async def connect(sid, environ):
209214 """Handle new client connected."""
210215 log .debug (f"TerminalSocket new client connected { sid } " )
211216 register_tmux ()
212- sio .start_background_task (
213- target = emit_output_continuously ,
214- )
217+
218+ global background_emit_task
219+ if background_emit_task is None :
220+ background_emit_task = asyncio .create_task (emit_output_continuously ())
215221
216222
217223@sio .on ("disconnect" , namespace = "/terminal" )
218224async def disconnect (sid ):
219225 """Handle client disconnect."""
226+ global background_emit_task
227+
228+ # If only this client (currently about to dc) is connected,
229+ # we can stop the repeatedly emitting task.
230+ if (
231+ background_emit_task is not None
232+ and len (sio .manager .rooms .get ("/terminal" , {}).get (None , set ())) == 1
233+ ):
234+ log .debug ("No more clients connected, stopping background emit task." )
235+ background_emit_task .cancel ()
236+ background_emit_task = None
237+ else :
238+ log .debug ("Clients still connected, keeping background emit task running." )
239+
220240 log .debug (f"TerminalSocket client disconnected { sid } " )
221241
222242
0 commit comments