mirror of
https://github.com/coder/coder.git
synced 2026-11-01 04:47:17 +08:00
Phase 1 of the Scalable Approach for Adding New IDE Session Types RFC, tracked in #27410. Gives agent session accounting one canonical vocabulary for app names, so later work can report a count per app without the agent and the server disagreeing about what an app is called. - Adds codersdk/appname.go: NormalizeAppName for storage and lookup, and AppFamilyName for the places that need a bounded value, such as a Prometheus label or the Connection_Type enum. - agentssh.Server keeps session counters in a map keyed by normalized name instead of three fixed atomics, dropping entries at zero. - Drops MagicSessionType. Sessions carry plain app names, and unrecognized ones flow through as themselves rather than collapsing to unknown. Wire behavior is unchanged: the agent still reports the four session_count_* fields over Agent API 2.10.
76 lines
2.6 KiB
Go
76 lines
2.6 KiB
Go
package codersdk
|
|
|
|
import (
|
|
"strings"
|
|
|
|
utilstrings "github.com/coder/coder/v2/coderd/util/strings"
|
|
)
|
|
|
|
// maxAppNameLength caps an app name in runes.
|
|
const maxAppNameLength = 64
|
|
|
|
// AppFamilyName is the bounded set of names that arbitrary app names group
|
|
// into, for callers that need a fixed value such as a metric label or the
|
|
// Connection_Type enum. Server-side only, not part of the HTTP API.
|
|
//
|
|
// @typescript-ignore AppFamilyName
|
|
type AppFamilyName string
|
|
|
|
const (
|
|
AppFamilyVSCode AppFamilyName = "vscode"
|
|
AppFamilyJetBrains AppFamilyName = "jetbrains"
|
|
AppFamilySSH AppFamilyName = "ssh"
|
|
AppFamilyReconnectingPTY AppFamilyName = "reconnecting_pty"
|
|
AppFamilyUnknown AppFamilyName = "unknown"
|
|
)
|
|
|
|
// appNameFamilies never gates storage, so a missing alias only costs an
|
|
// AppFamilyUnknown label. Keys are the IDs Coder's registry modules use.
|
|
var appNameFamilies = map[string]AppFamilyName{
|
|
"vscode": AppFamilyVSCode,
|
|
"vscode_insiders": AppFamilyVSCode,
|
|
"vscode_web": AppFamilyVSCode,
|
|
"code_server": AppFamilyVSCode,
|
|
"cursor": AppFamilyVSCode,
|
|
"windsurf": AppFamilyVSCode,
|
|
"positron": AppFamilyVSCode,
|
|
"vscodium": AppFamilyVSCode,
|
|
"codium": AppFamilyVSCode,
|
|
"antigravity": AppFamilyVSCode,
|
|
"trae": AppFamilyVSCode,
|
|
"kiro": AppFamilyVSCode,
|
|
"devin": AppFamilyVSCode,
|
|
|
|
"jetbrains": AppFamilyJetBrains,
|
|
// Zed has no Connection_Type or session count field of its own, so it
|
|
// rolls up under SSH. The raw name still reaches storage.
|
|
"zed": AppFamilySSH,
|
|
"ssh": AppFamilySSH,
|
|
"reconnecting_pty": AppFamilyReconnectingPTY,
|
|
}
|
|
|
|
// AppNameFamily normalizes an app name and returns its family, or
|
|
// AppFamilyUnknown.
|
|
func AppNameFamily(appName string) AppFamilyName {
|
|
if family, ok := appNameFamilies[NormalizeAppName(appName)]; ok {
|
|
return family
|
|
}
|
|
return AppFamilyUnknown
|
|
}
|
|
|
|
// NormalizeAppName prepares a client-supplied app name for storage and
|
|
// lookup: it strips the null bytes Postgres TEXT rejects, trims, truncates,
|
|
// lowercases, and folds hyphens to underscores. Empty becomes
|
|
// AppFamilyUnknown.
|
|
func NormalizeAppName(appName string) string {
|
|
appName = strings.ReplaceAll(appName, "\x00", "")
|
|
// Trim before truncating so padding does not spend the budget, and after
|
|
// in case the cut lands in whitespace.
|
|
appName = strings.TrimSpace(appName)
|
|
appName = strings.TrimSpace(utilstrings.Truncate(appName, maxAppNameLength))
|
|
if appName == "" {
|
|
return string(AppFamilyUnknown)
|
|
}
|
|
return strings.ReplaceAll(strings.ToLower(appName), "-", "_")
|
|
}
|