Documentation
¶
Overview ¶
Package tracker manages active WebSocket connections and auto-hibernation for StreamSpace sessions.
The tracker provides:
- Real-time connection tracking (WebSocket, VNC, HTTP)
- Heartbeat monitoring with configurable timeout
- Auto-start of hibernated sessions when connections arrive
- Auto-hibernate idle sessions with zero active connections
- Connection statistics and monitoring
Architecture:
- In-memory connection map for fast lookups
- PostgreSQL persistence for connection history
- Kubernetes integration for session state management
- Background goroutine for periodic connection checks
Lifecycle:
- User connects to session → AddConnection()
- Periodic heartbeats → UpdateHeartbeat()
- Connection lost → RemoveConnection()
- No connections + idle timeout → Auto-hibernate
Configuration:
- checkInterval: 30 seconds (how often to check connections)
- heartbeatWindow: 60 seconds (max time without heartbeat)
Example usage:
tracker := NewConnectionTracker(database, k8sClient)
go tracker.Start()
// When user connects via WebSocket
conn := &Connection{
ID: uuid.New().String(),
SessionID: sessionID,
UserID: userID,
ConnectedAt: time.Now(),
LastHeartbeat: time.Now(),
}
tracker.AddConnection(ctx, conn)
Index ¶
- type Connection
- type ConnectionTracker
- func (ct *ConnectionTracker) AddConnection(ctx context.Context, conn *Connection) error
- func (ct *ConnectionTracker) GetActiveConnections(sessionID string) []*Connection
- func (ct *ConnectionTracker) GetConnection(connectionID string) *Connection
- func (ct *ConnectionTracker) GetConnectionCount(sessionID string) int
- func (ct *ConnectionTracker) GetStats() map[string]interface{}
- func (ct *ConnectionTracker) RemoveConnection(ctx context.Context, connectionID string) error
- func (ct *ConnectionTracker) Start()
- func (ct *ConnectionTracker) Stop()
- func (ct *ConnectionTracker) UpdateHeartbeat(ctx context.Context, connectionID string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Connection ¶
type Connection struct {
// ID is a unique identifier for this connection.
// Format: UUID or similar unique string
ID string
// SessionID is the session this connection is for.
// Must match a valid session ID in database
SessionID string
// UserID is the authenticated user who owns this connection.
UserID string
// ClientIP is the IP address of the client.
// Used for security auditing and geo-location
ClientIP string
// UserAgent is the browser/client user agent string.
// Used for analytics and compatibility tracking
UserAgent string
// ConnectedAt is when this connection was established.
ConnectedAt time.Time
// LastHeartbeat is the last time this connection sent a heartbeat.
// Connections without recent heartbeats are considered stale.
LastHeartbeat time.Time
}
Connection represents an active user connection to a session.
Connections are created when:
- User opens VNC viewer
- User opens session in browser
- API client establishes WebSocket
Connections are tracked for:
- Auto-hibernation (hibernate when count reaches zero)
- Usage analytics (connection duration, IP addresses)
- Concurrent user limits
- Session sharing detection
Example:
conn := &Connection{
ID: "conn-abc123",
SessionID: "user1-firefox",
UserID: "user1",
ClientIP: "192.168.1.100",
UserAgent: "Mozilla/5.0...",
ConnectedAt: time.Now(),
LastHeartbeat: time.Now(),
}
type ConnectionTracker ¶
type ConnectionTracker struct {
// contains filtered or unexported fields
}
ConnectionTracker manages active connections and implements auto-hibernation.
Thread safety:
- Uses sync.RWMutex for concurrent access
- Safe for multiple goroutines to call AddConnection/RemoveConnection
- Background checker runs in separate goroutine
Hibernation logic:
- Session is hibernated when activeConnections == 0 AND idle timeout elapsed
- Session is auto-started when new connection arrives while hibernated
- Heartbeat window prevents premature disconnection (grace period)
Database persistence:
- All connections are persisted to PostgreSQL
- Connection history enables usage analytics
- On startup, loads active connections from last 5 minutes
func NewConnectionTracker ¶
func NewConnectionTracker(database *db.Database, k8sClient *k8s.Client, publisher *events.Publisher, platform string) *ConnectionTracker
NewConnectionTracker creates a new connection tracker instance.
Default configuration:
- checkInterval: 30 seconds (connection health checks)
- heartbeatWindow: 60 seconds (heartbeat timeout)
The tracker must be started with Start() to begin monitoring.
Example:
tracker := NewConnectionTracker(database, k8sClient, publisher, "kubernetes") go tracker.Start() // Run in background
func (*ConnectionTracker) AddConnection ¶
func (ct *ConnectionTracker) AddConnection(ctx context.Context, conn *Connection) error
AddConnection registers a new connection and triggers auto-start if needed.
This method:
- Adds connection to in-memory map
- Persists connection to database
- Updates session last_connection timestamp
- Increments session active_connections count
- Triggers auto-start if session is hibernated (async)
Auto-start behavior:
- Runs in background goroutine (doesn't block)
- Only starts sessions in "hibernated" state
- Updates Kubernetes Session resource to state="running"
Parameters:
- ctx: Context for database operations
- conn: Connection to add (must have valid ID, SessionID, UserID)
Returns an error if:
- Database insert fails
- Session update fails
Example:
conn := &Connection{
ID: uuid.New().String(),
SessionID: sessionID,
UserID: userID,
ClientIP: r.RemoteAddr,
UserAgent: r.UserAgent(),
ConnectedAt: time.Now(),
LastHeartbeat: time.Now(),
}
err := tracker.AddConnection(ctx, conn)
func (*ConnectionTracker) GetActiveConnections ¶
func (ct *ConnectionTracker) GetActiveConnections(sessionID string) []*Connection
GetActiveConnections returns all active connections for a session
func (*ConnectionTracker) GetConnection ¶
func (ct *ConnectionTracker) GetConnection(connectionID string) *Connection
GetConnection returns a connection by ID, or nil if not found
func (*ConnectionTracker) GetConnectionCount ¶
func (ct *ConnectionTracker) GetConnectionCount(sessionID string) int
GetConnectionCount returns the number of active connections for a session
func (*ConnectionTracker) GetStats ¶
func (ct *ConnectionTracker) GetStats() map[string]interface{}
GetStats returns connection statistics
func (*ConnectionTracker) RemoveConnection ¶
func (ct *ConnectionTracker) RemoveConnection(ctx context.Context, connectionID string) error
RemoveConnection removes a connection
func (*ConnectionTracker) Start ¶
func (ct *ConnectionTracker) Start()
Start begins the connection tracking loop.
This method:
- Loads active connections from database (last 5 minutes)
- Starts periodic checker (runs every checkInterval)
- Checks connection health and performs auto-hibernation
- Runs until Stop() is called
This is a blocking call and should be run in a goroutine:
go tracker.Start()
The checker performs these operations on each tick:
- Count active connections per session
- Remove stale connections (no heartbeat)
- Update database connection counts
- Auto-hibernate sessions with zero connections
func (*ConnectionTracker) Stop ¶
func (ct *ConnectionTracker) Stop()
Stop stops the connection tracker
func (*ConnectionTracker) UpdateHeartbeat ¶
func (ct *ConnectionTracker) UpdateHeartbeat(ctx context.Context, connectionID string) error
UpdateHeartbeat updates the last heartbeat time for a connection