@@ -48,6 +48,7 @@ import (
4848
4949const END_OF_TRANSMISSION = "\u0004 "
5050const ProcessExitedMsg = "Process exited"
51+ const ProcessTimedOut = "Process timedOut"
5152
5253// PtyHandler is what remotecommand expects from a pty
5354type PtyHandler interface {
@@ -185,23 +186,53 @@ func (sm *SessionMap) SetTerminalSessionStartTime(sessionId string) {
185186 }
186187}
187188
189+ func (sm * SessionMap ) setAndSendSignal (sessionId string , session sockjs.Session ) {
190+ sm .Lock .Lock ()
191+ defer sm .Lock .Unlock ()
192+ terminalSession , ok := sm .Sessions [sessionId ]
193+ if ok && terminalSession .id == "" {
194+ log .Printf ("handleTerminalSession: can't find session '%s'" , sessionId )
195+ session .Close (http .StatusGone , fmt .Sprintf ("handleTerminalSession: can't find session '%s'" , sessionId ))
196+ return
197+ } else if ok {
198+ terminalSession .sockJSSession = session
199+ sm .Sessions [sessionId ] = terminalSession
200+
201+ select {
202+ case terminalSession .bound <- nil :
203+ log .Printf ("message sent on bound channel for sessionId : %s" , sessionId )
204+ default :
205+ // if a request from the front end is not received within a particular time frame, and no one is reading from the bound channel, we will ignore sending on the bound channel.
206+ log .Printf ("skipping send on bound, channel receiver possibly timed out. sessionId: %s" , sessionId )
207+ }
208+
209+ }
210+ }
211+
188212// Close shuts down the SockJS connection and sends the status code and reason to the client
189213// Can happen if the process exits or if there is an error starting up the process
190214// For now the status code is unused and reason is shown to the user (unless "")
191215func (sm * SessionMap ) Close (sessionId string , status uint32 , reason string ) {
216+
192217 sm .Lock .Lock ()
193218 defer sm .Lock .Unlock ()
219+
194220 terminalSession := sm .Sessions [sessionId ]
221+
195222 if terminalSession .sockJSSession != nil {
223+
196224 err := terminalSession .sockJSSession .Close (status , reason )
197225 if err != nil {
198226 log .Println (err )
199227 }
228+
229+ close (terminalSession .doneChan )
230+
200231 isErroredConnectionTermination := isConnectionClosedByError (status )
201232 middleware .IncTerminalSessionRequestCounter (SessionTerminated , strconv .FormatBool (isErroredConnectionTermination ))
202233 middleware .RecordTerminalSessionDurationMetrics (terminalSession .podName , terminalSession .namespace , terminalSession .clusterId , time .Since (terminalSession .startedOn ).Seconds ())
203- close (terminalSession .doneChan )
204234 terminalSession .contextCancelFunc ()
235+ close (terminalSession .bound )
205236 delete (sm .Sessions , sessionId )
206237 }
207238
@@ -219,10 +250,9 @@ var terminalSessions = SessionMap{Sessions: make(map[string]TerminalSession)}
219250// handleTerminalSession is Called by net/http for any new /api/sockjs connections
220251func handleTerminalSession (session sockjs.Session ) {
221252 var (
222- buf string
223- err error
224- msg TerminalMessage
225- terminalSession TerminalSession
253+ buf string
254+ err error
255+ msg TerminalMessage
226256 )
227257
228258 if buf , err = session .Recv (); err != nil {
@@ -241,15 +271,8 @@ func handleTerminalSession(session sockjs.Session) {
241271 return
242272 }
243273
244- if terminalSession = terminalSessions .Get (msg .SessionID ); terminalSession .id == "" {
245- log .Printf ("handleTerminalSession: can't find session '%s'" , msg .SessionID )
246- session .Close (http .StatusGone , fmt .Sprintf ("handleTerminalSession: can't find session '%s'" , msg .SessionID ))
247- return
248- }
274+ terminalSessions .setAndSendSignal (msg .SessionID , session )
249275
250- terminalSession .sockJSSession = session
251- terminalSessions .Set (msg .SessionID , terminalSession )
252- terminalSession .bound <- nil
253276}
254277
255278type SocketConfig struct {
@@ -381,7 +404,6 @@ func WaitForTerminal(k8sClient kubernetes.Interface, cfg *rest.Config, request *
381404 timedCtx , _ := context .WithTimeout (sessionCtx , 60 * time .Second )
382405 select {
383406 case <- session .bound :
384- close (session .bound )
385407
386408 var err error
387409 if isValidShell (validShells , request .Shell ) {
@@ -407,8 +429,7 @@ func WaitForTerminal(k8sClient kubernetes.Interface, cfg *rest.Config, request *
407429 terminalSessions .Close (request .SessionId , 1 , ProcessExitedMsg )
408430 case <- timedCtx .Done ():
409431 // handle case when connection has not been initiated from FE side within particular time
410- close (session .bound )
411- terminalSessions .Close (request .SessionId , 1 , ProcessExitedMsg )
432+ terminalSessions .Close (request .SessionId , 1 , ProcessTimedOut )
412433 }
413434}
414435
0 commit comments