Documentation
¶
Index ¶
- Constants
- Variables
- type Connection
- type ErrorCategory
- type ErrorLocation
- type ExecutionRecord
- type Game
- type GlobalJSSnapshot
- type IntervalExecInfo
- type IntervalExecSnapshot
- type IntervalExecStats
- type IntervalSortField
- type InvalidUsernameError
- type JSStats
- func (s *JSStats) GlobalSnapshot() GlobalJSSnapshot
- func (s *JSStats) ObjectExecSnapshot(objectID string) *ObjectExecSnapshot
- func (s *JSStats) RecentErrors(n int) []ExecutionRecord
- func (s *JSStats) RecentRecords(n int, filter func(*ExecutionRecord) bool) []ExecutionRecord
- func (s *JSStats) RecentSlowExecutions(n int) []ExecutionRecord
- func (s *JSStats) RecordBootError(err error)
- func (s *JSStats) RecordError(sourcePath, objectID string, err error, duration time.Duration, ...)
- func (s *JSStats) RecordExecution(sourcePath, objectID string, duration time.Duration, ...)
- func (s *JSStats) RecordLoadError(objectID string, err error)
- func (s *JSStats) RecordRecoveryError(objectID, intervalID string, err error)
- func (s *JSStats) Reset()
- func (s *JSStats) ScriptSnapshot(sourcePath string) *ScriptSnapshot
- func (s *JSStats) TopIntervals(by IntervalSortField, n int) []IntervalExecSnapshot
- func (s *JSStats) TopLocations(n int) []LocationSnapshot
- func (s *JSStats) TopObjects(by ObjectSortField, n int) []ObjectExecSnapshot
- func (s *JSStats) TopScripts(by ScriptSortField, n int) []ScriptSnapshot
- func (s *JSStats) UpdateRates()
- type LocationSnapshot
- type LocationStats
- type ObjectExecSnapshot
- type ObjectExecStats
- type ObjectSortField
- type RWMutex
- type RateSnapshot
- type RateStats
- type ScriptSnapshot
- type ScriptSortField
- type ScriptStats
- type SortField
- type Switchboard
- func (s *Switchboard) Attach(objectID string, t *term.Terminal)
- func (s *Switchboard) Detach(objectID string, t *term.Terminal)
- func (s *Switchboard) GetBuffered(objectID string) [][]byte
- func (s *Switchboard) IsAttached(objectID string, t *term.Terminal) bool
- func (s *Switchboard) Writer(objectID string) *SwitchboardWriter
- type SwitchboardWriter
- type TimeRateSnapshot
- type TimeRateStats
Constants ¶
const ( SortScriptByTime = SortByTime SortScriptByExecs = SortByExecs SortScriptBySlow = SortBySlow SortScriptByErrors = SortByErrors SortScriptByErrorRate = SortByErrorRate )
const ( SortObjectByTime = SortByTime SortObjectByExecs = SortByExecs SortObjectBySlow = SortBySlow SortObjectByErrors = SortByErrors SortObjectByErrorRate = SortByErrorRate )
const ( SortIntervalByTime = SortByTime SortIntervalByExecs = SortByExecs SortIntervalBySlow = SortBySlow SortIntervalByErrors = SortByErrors SortIntervalByErrorRate = SortByErrorRate )
Variables ¶
var (
ErrOperationAborted = fmt.Errorf("operation aborted")
)
Functions ¶
This section is empty.
Types ¶
type Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
func (*Connection) Connect ¶
func (c *Connection) Connect() error
func (*Connection) Process ¶
func (c *Connection) Process() error
func (*Connection) SelectExec ¶
func (c *Connection) SelectExec(options map[string]func() error) error
func (*Connection) SelectReturn ¶
func (c *Connection) SelectReturn(prompt string, options []string) (string, error)
func (*Connection) TermWidth ¶
func (c *Connection) TermWidth() int
TermWidth returns the terminal width in columns. Falls back to defaultTermWidth if PTY info is unavailable.
type ErrorCategory ¶
type ErrorCategory string
ErrorCategory classifies the source of an error.
const ( CategoryJS ErrorCategory = "js" CategoryStorage ErrorCategory = "storage" CategoryTimeout ErrorCategory = "timeout" CategoryJSON ErrorCategory = "json" CategoryOther ErrorCategory = "other" )
type ErrorLocation ¶
ErrorLocation represents where an error occurred (file:line:column). All fields are optional - nil/empty means not available.
func (ErrorLocation) String ¶
func (l ErrorLocation) String() string
type ExecutionRecord ¶
type ExecutionRecord struct {
Timestamp time.Time
ObjectID string
SourcePath string
IntervalID string // Empty if not an interval event
Duration time.Duration // 0 for non-execution errors (boot, load)
IsError bool
Category ErrorCategory // Only set if IsError
Location ErrorLocation // Only set if IsError
Message string // Only set if IsError (truncated)
ImportChain []string // For slow executions
}
ExecutionRecord captures a notable execution (error or slow) for debugging.
type Game ¶
type Game struct {
// contains filtered or unexported fields
}
func New ¶
New creates a new Game instance. If firstStartup is true (server directory was just created), it creates all initial source files. On all startups, it ensures fundamental objects exist (genesis, empty) so the server can function, but uses SetIfMissing to preserve any admin customizations to existing objects.
func (*Game) Context ¶
Context creates a structs.Context that combines the given context with game time (from Queue) and server config. This is used for skill checks and other operations that need both timing and configuration.
func (*Game) GetServerConfig ¶
func (g *Game) GetServerConfig() *structs.ServerConfig
GetServerConfig returns the server config. Thread-safe access is handled by the ServerConfig's internal mutex.
func (*Game) HandleSession ¶
func (*Game) RecoverIntervals ¶
RecoverIntervals loads all intervals from persistent storage and enqueues them. Called at startup to restore interval functionality after a server restart. Uses NextFireTime to determine scheduling: - If in future: enqueue at that time (clean shutdown, timing preserved) - If in past: calculate missed intervals and enqueue for now Uses atomic Update to avoid race conditions with concurrent operations.
type GlobalJSSnapshot ¶
type GlobalJSSnapshot struct {
// Execution stats
TotalExecs uint64
TotalTimeMs float64 // Total milliseconds of JS execution
AvgTimeMs float64
TotalSlow uint64
SlowPercent float64
Uptime time.Duration
ExecRates RateSnapshot
TimeRates TimeRateSnapshot
// Error stats
TotalErrors uint64
ErrorPercent float64 // errors/executions ratio
ByCategory map[ErrorCategory]uint64
ErrorRates RateSnapshot
}
GlobalJSSnapshot contains overall JS execution and error statistics.
type IntervalExecInfo ¶
IntervalExecInfo contains interval metadata for execution recording.
type IntervalExecSnapshot ¶
type IntervalExecSnapshot struct {
// Identity
IntervalID string
ObjectID string
EventName string
// Execution stats
Executions uint64
AvgTimeMs float64
MinTimeMs float64
MaxTimeMs float64
SlowCount uint64
SlowPercent float64
LastExecution time.Time
ExecRates RateSnapshot
TimeRates TimeRateSnapshot
// Error stats
Errors uint64
ErrorPercent float64 // errors/executions ratio
LastError time.Time
ByCategory map[ErrorCategory]uint64
ByLocation map[string]uint64
ErrorRates RateSnapshot
}
IntervalExecSnapshot contains execution and error stats for one interval.
type IntervalExecStats ¶
type IntervalExecStats struct {
// Execution stats
Executions uint64 // Total execution count
TotalTimeNs uint64 // Total execution time in nanoseconds
MinTimeNs uint64 // Minimum execution time (valid only if Executions > 0)
MaxTimeNs uint64 // Maximum execution time
SlowCount uint64 // Executions exceeding threshold
LastExecution time.Time // Last execution timestamp
ObjectID string // Owner object ID
EventName string // Event name for this interval
// Error stats
Errors uint64 // Total error count
LastError time.Time // Last error timestamp
ByCategory map[ErrorCategory]uint64
ByLocation map[string]uint64 // error location string -> count
// contains filtered or unexported fields
}
IntervalExecStats tracks per-interval execution and error statistics.
type IntervalSortField ¶
type IntervalSortField = SortField
IntervalSortField specifies how to sort interval results. Deprecated: Use SortField instead.
type InvalidUsernameError ¶
type InvalidUsernameError struct{}
InvalidUsernameError is returned when a username fails validation.
func (InvalidUsernameError) Error ¶
func (e InvalidUsernameError) Error() string
type JSStats ¶
type JSStats struct {
// contains filtered or unexported fields
}
JSStats tracks JavaScript execution and error statistics. It monitors execution times, errors per-script/object/interval, identifies slow executions, and provides EMA-based rate tracking.
Thread safety: While the underlying caches are internally thread-safe for individual operations (Get, Set, etc.), we use an external mutex (mu) to ensure atomicity of read-modify-write sequences. Without it, concurrent goroutines could both Get() returning nil, both create new stat objects, and one would overwrite the other's modifications. The external RLock is used for read-only snapshot operations with Peek().
func NewJSStats ¶
NewJSStats creates a new JSStats tracker and starts the periodic rate update loop. The loop runs until the context is cancelled.
func NewJSStatsWithTTL ¶
NewJSStatsWithTTL creates a new JSStats tracker with a custom TTL. This is useful for testing with shorter TTL values.
func (*JSStats) GlobalSnapshot ¶
func (s *JSStats) GlobalSnapshot() GlobalJSSnapshot
GlobalSnapshot returns overall JS execution and error statistics.
func (*JSStats) ObjectExecSnapshot ¶
func (s *JSStats) ObjectExecSnapshot(objectID string) *ObjectExecSnapshot
ObjectSnapshot returns stats for a specific object, or nil if not found.
func (*JSStats) RecentErrors ¶
func (s *JSStats) RecentErrors(n int) []ExecutionRecord
RecentErrors returns the n most recent error executions, newest first.
func (*JSStats) RecentRecords ¶
func (s *JSStats) RecentRecords(n int, filter func(*ExecutionRecord) bool) []ExecutionRecord
RecentRecords returns the n most recent notable executions (errors + slow), newest first. Use filter to select specific record types: nil for all, or a function like func(r *ExecutionRecord) bool { return r.IsError }.
func (*JSStats) RecentSlowExecutions ¶
func (s *JSStats) RecentSlowExecutions(n int) []ExecutionRecord
RecentSlowExecutions returns the n most recent slow executions (non-errors), newest first.
func (*JSStats) RecordBootError ¶
RecordBootError records a boot.js execution error. Boot JS doesn't go through run(), so it needs separate handling. err is the error that occurred during boot.js execution.
func (*JSStats) RecordError ¶
func (s *JSStats) RecordError(sourcePath, objectID string, err error, duration time.Duration, intervalInfo *IntervalExecInfo)
RecordError records a JavaScript execution error with its context. This should be called from run() when JS execution fails. sourcePath is the source file path (e.g., "/user.js"). objectID is the object that executed the script. err is the error that occurred. duration is the execution time up until the error (0 if unknown, may be partial). intervalInfo is optional interval metadata (nil for non-interval events).
func (*JSStats) RecordExecution ¶
func (s *JSStats) RecordExecution(sourcePath, objectID string, duration time.Duration, intervalInfo *IntervalExecInfo)
RecordExecution records a JavaScript execution with its duration. sourcePath is the source file path (e.g., "/user.js"). objectID is the object that executed the script. duration is the execution time. intervalInfo is optional interval metadata (nil for non-interval events).
func (*JSStats) RecordLoadError ¶
RecordLoadError records a pre-run loading error (e.g., AccessObject failure). This is called from loadRun() when the object cannot be loaded before JS execution. objectID is the object that failed to load. err is the error that occurred.
func (*JSStats) RecordRecoveryError ¶
RecordRecoveryError records an interval recovery or re-enqueue error. These are operational errors, not JS execution errors. objectID is the object the interval belongs to. intervalID is the interval that failed recovery. err is the error that occurred.
func (*JSStats) ScriptSnapshot ¶
func (s *JSStats) ScriptSnapshot(sourcePath string) *ScriptSnapshot
ScriptSnapshot returns stats for a specific script, or nil if not found.
func (*JSStats) TopIntervals ¶
func (s *JSStats) TopIntervals(by IntervalSortField, n int) []IntervalExecSnapshot
TopIntervals returns the top n intervals sorted by the specified field.
func (*JSStats) TopLocations ¶
func (s *JSStats) TopLocations(n int) []LocationSnapshot
TopLocations returns the top n error locations by count.
func (*JSStats) TopObjects ¶
func (s *JSStats) TopObjects(by ObjectSortField, n int) []ObjectExecSnapshot
TopObjects returns the top n objects sorted by the specified field.
func (*JSStats) TopScripts ¶
func (s *JSStats) TopScripts(by ScriptSortField, n int) []ScriptSnapshot
TopScripts returns the top n scripts sorted by the specified field.
func (*JSStats) UpdateRates ¶
func (s *JSStats) UpdateRates()
UpdateRates should be called periodically to update EMA rate calculations. It also triggers cleanup of expired cache entries.
type LocationSnapshot ¶
type LocationSnapshot struct {
Location string
Count uint64
FirstSeen time.Time
LastSeen time.Time
}
LocationSnapshot contains error stats for one code location.
type LocationStats ¶
type LocationStats struct {
Location string // The location string (e.g., "/user.js:42:15")
Count uint64 // Total error count at this location
FirstSeen time.Time // When this location was first seen
LastSeen time.Time // Most recent error at this location
}
LocationStats tracks error statistics for a code location (file:line:col).
type ObjectExecSnapshot ¶
type ObjectExecSnapshot struct {
// Identity
ObjectID string
SourcePath string
// Execution stats
Executions uint64
AvgTimeMs float64
MinTimeMs float64
MaxTimeMs float64
SlowCount uint64
SlowPercent float64
LastExecution time.Time
ExecRates RateSnapshot
TimeRates TimeRateSnapshot
// Error stats
Errors uint64
ErrorPercent float64 // errors/executions ratio
LastError time.Time
ByCategory map[ErrorCategory]uint64
ByLocation map[string]uint64
ByScript map[string]uint64
ErrorRates RateSnapshot
}
ObjectExecSnapshot contains execution and error stats for one object.
type ObjectExecStats ¶
type ObjectExecStats struct {
// Execution stats
Executions uint64 // Total execution count
TotalTimeNs uint64 // Total execution time in nanoseconds
MinTimeNs uint64 // Minimum execution time (valid only if Executions > 0)
MaxTimeNs uint64 // Maximum execution time
SlowCount uint64 // Executions exceeding threshold
LastExecution time.Time // Last execution timestamp
SourcePath string // Current source path for this object
// Error stats
Errors uint64 // Total error count
LastError time.Time // Last error timestamp
ByCategory map[ErrorCategory]uint64
ByLocation map[string]uint64 // error location string -> count
ByScript map[string]uint64 // script path -> error count
// contains filtered or unexported fields
}
ObjectExecStats tracks per-object execution and error statistics.
type ObjectSortField ¶
type ObjectSortField = SortField
ObjectSortField specifies how to sort object results. Deprecated: Use SortField instead.
type RateSnapshot ¶
type RateSnapshot struct {
PerSecond float64 // Events/second, 1s EMA window
PerMinute float64 // Events/second, 1m EMA window
PerHour float64 // Events/second, 1h EMA window
PerDay float64 // Events/second, 24h EMA window
}
RateSnapshot contains EMA rates for display. All rates are events-per-second, smoothed over different time windows. PerSecond is reactive (1s window), PerMinute is smoother (1m window), etc.
type RateStats ¶
type RateStats struct {
SecondRate float64 // EMA over ~1 second
MinuteRate float64 // EMA over ~1 minute
HourRate float64 // EMA over ~1 hour
DayRate float64 // EMA over ~1 day
// contains filtered or unexported fields
}
RateStats tracks EMA of event counts (events per second).
type ScriptSnapshot ¶
type ScriptSnapshot struct {
// Identity
SourcePath string
// Execution stats
Executions uint64
AvgTimeMs float64
MinTimeMs float64
MaxTimeMs float64
SlowCount uint64
SlowPercent float64
LastExecution time.Time
ImportChain []string
ExecRates RateSnapshot
TimeRates TimeRateSnapshot
// Error stats
Errors uint64
ErrorPercent float64 // errors/executions ratio
LastError time.Time
ByCategory map[ErrorCategory]uint64
ByLocation map[string]uint64
ErrorRates RateSnapshot
}
ScriptSnapshot contains stats for one script path.
type ScriptSortField ¶
type ScriptSortField = SortField
ScriptSortField specifies how to sort script results. Deprecated: Use SortField instead.
type ScriptStats ¶
type ScriptStats struct {
// Execution stats
Executions uint64 // Total execution count
TotalTimeNs uint64 // Total execution time in nanoseconds
MinTimeNs uint64 // Minimum execution time (valid only if Executions > 0)
MaxTimeNs uint64 // Maximum execution time
SlowCount uint64 // Executions exceeding threshold
LastExecution time.Time // Last execution timestamp
// Error stats
Errors uint64 // Total error count
LastError time.Time // Last error timestamp
ByCategory map[ErrorCategory]uint64
ByLocation map[string]uint64 // error location string -> count
// contains filtered or unexported fields
}
ScriptStats tracks per-script (source path) execution and error statistics.
type SortField ¶
type SortField int
SortField is a unified sort field type for scripts, objects, and intervals. All entity types use the same sort criteria (time, execs, slow, errors, error rate).
type Switchboard ¶
type Switchboard struct {
// contains filtered or unexported fields
}
Switchboard manages debug console connections from wizards to objects. It provides a Writer for each object that broadcasts to all attached terminals. Also maintains a ring buffer of recent messages per object.
func NewSwitchboard ¶
func NewSwitchboard(ctx context.Context) *Switchboard
NewSwitchboard creates a new console switchboard and starts the cleanup goroutine. The cleanup goroutine runs until ctx is cancelled.
func (*Switchboard) Attach ¶
func (s *Switchboard) Attach(objectID string, t *term.Terminal)
Attach connects a terminal to receive debug output from an object. Nil terminals are ignored.
func (*Switchboard) Detach ¶
func (s *Switchboard) Detach(objectID string, t *term.Terminal)
Detach disconnects a terminal from an object's debug output.
func (*Switchboard) GetBuffered ¶
func (s *Switchboard) GetBuffered(objectID string) [][]byte
GetBuffered returns all non-expired buffered messages for an object in chronological order. Returns nil if no messages are buffered or all have expired. Also cleans up the buffer entry if all messages have expired.
func (*Switchboard) IsAttached ¶
func (s *Switchboard) IsAttached(objectID string, t *term.Terminal) bool
IsAttached returns true if the terminal is attached to the object.
func (*Switchboard) Writer ¶
func (s *Switchboard) Writer(objectID string) *SwitchboardWriter
Writer returns an io.Writer that broadcasts to all terminals attached to the object. Failed writes automatically detach the terminal.
Note: Due to lock-free I/O (to avoid deadlocks with slow terminals), a terminal may receive one additional write after being detached if a Write() was already in progress when Detach() was called.
type SwitchboardWriter ¶
type SwitchboardWriter struct {
// contains filtered or unexported fields
}
SwitchboardWriter broadcasts writes to all terminals attached to an object. Must be created via Switchboard.Writer(), not instantiated directly.
func (*SwitchboardWriter) Write ¶
func (w *SwitchboardWriter) Write(b []byte) (int, error)
Write implements io.Writer. For broadcast semantics, this always returns (len(b), nil) as long as the write is attempted, even if some terminals fail. Failed terminals are automatically detached from the switchboard. All messages are also stored in the ring buffer for later retrieval.
type TimeRateSnapshot ¶
type TimeRateSnapshot struct {
PerSecond float64 // JS sec/wall sec, 1s EMA window
PerMinute float64 // JS sec/wall sec, 1m EMA window
PerHour float64 // JS sec/wall sec, 1h EMA window
PerDay float64 // JS sec/wall sec, 24h EMA window
}
TimeRateSnapshot contains EMA of execution time rates. All rates are JS-seconds per wall-second, smoothed over different time windows.
type TimeRateStats ¶
type TimeRateStats struct {
SecondRate float64 // Seconds of JS per second of wall time
MinuteRate float64 // Seconds of JS per minute of wall time
HourRate float64 // Seconds of JS per hour of wall time
DayRate float64 // Seconds of JS per day of wall time
// contains filtered or unexported fields
}
TimeRateStats tracks EMA of execution time (seconds of JS per second of wall time). This is distinct from RateStats which tracks event counts.