mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"cdr.dev/slog"
|
||||
"github.com/coder/coder/agent/agentssh"
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
"github.com/coder/coder/coderd/httpmw"
|
||||
"github.com/coder/coder/coderd/tracing"
|
||||
@@ -109,7 +110,8 @@ type Server struct {
|
||||
DisablePathApps bool
|
||||
SecureAuthCookie bool
|
||||
|
||||
AgentProvider AgentProvider
|
||||
AgentProvider AgentProvider
|
||||
StatsCollector *StatsCollector
|
||||
|
||||
websocketWaitMutex sync.Mutex
|
||||
websocketWaitGroup sync.WaitGroup
|
||||
@@ -122,6 +124,10 @@ func (s *Server) Close() error {
|
||||
s.websocketWaitGroup.Wait()
|
||||
s.websocketWaitMutex.Unlock()
|
||||
|
||||
if s.StatsCollector != nil {
|
||||
_ = s.StatsCollector.Close()
|
||||
}
|
||||
|
||||
// The caller must close the SignedTokenProvider and the AgentProvider (if
|
||||
// necessary).
|
||||
|
||||
@@ -586,6 +592,14 @@ func (s *Server) proxyWorkspaceApp(rw http.ResponseWriter, r *http.Request, appT
|
||||
// end span so we don't get long lived trace data
|
||||
tracing.EndHTTPSpan(r, http.StatusOK, trace.SpanFromContext(ctx))
|
||||
|
||||
report := newStatsReportFromSignedToken(appToken)
|
||||
s.collectStats(report)
|
||||
defer func() {
|
||||
// We must use defer here because ServeHTTP may panic.
|
||||
report.SessionEndedAt = database.Now()
|
||||
s.collectStats(report)
|
||||
}()
|
||||
|
||||
proxy.ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
@@ -678,10 +692,24 @@ func (s *Server) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer ptNetConn.Close()
|
||||
log.Debug(ctx, "obtained PTY")
|
||||
|
||||
report := newStatsReportFromSignedToken(*appToken)
|
||||
s.collectStats(report)
|
||||
defer func() {
|
||||
report.SessionEndedAt = database.Now()
|
||||
s.collectStats(report)
|
||||
}()
|
||||
|
||||
agentssh.Bicopy(ctx, wsNetConn, ptNetConn)
|
||||
log.Debug(ctx, "pty Bicopy finished")
|
||||
}
|
||||
|
||||
func (s *Server) collectStats(stats StatsReport) {
|
||||
if s.StatsCollector != nil {
|
||||
s.StatsCollector.Collect(stats)
|
||||
}
|
||||
}
|
||||
|
||||
// wsNetConn wraps net.Conn created by websocket.NetConn(). Cancel func
|
||||
// is called if a read or write error is encountered.
|
||||
type wsNetConn struct {
|
||||
|
||||
Reference in New Issue
Block a user