tracker

package
v0.0.0-...-e5d423c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 9 Imported by: 0

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:

  1. User connects to session → AddConnection()
  2. Periodic heartbeats → UpdateHeartbeat()
  3. Connection lost → RemoveConnection()
  4. 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

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:

  1. Adds connection to in-memory map
  2. Persists connection to database
  3. Updates session last_connection timestamp
  4. Increments session active_connections count
  5. 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:

  1. Loads active connections from database (last 5 minutes)
  2. Starts periodic checker (runs every checkInterval)
  3. Checks connection health and performs auto-hibernation
  4. 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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL