How CasaOS Manages Periodic Tasks Using Cron: Hardware Status Scheduling Explained
CasaOS uses the robfig/cron library with second-level precision to schedule background jobs, creating independent cron.Cron instances that execute functions like SendAllHardwareStatusBySocket every five seconds for real-time system monitoring without blocking the main HTTP server.
The IceWhaleTech/CasaOS repository implements a robust scheduling mechanism for recurring maintenance and monitoring operations. By leveraging the popular robfig/cron library, CasaOS can execute periodic tasks such as gathering CPU, memory, and network statistics while keeping the system responsive.
The Cron Architecture in CasaOS
CasaOS relies on the third-party robfig/cron library (specifically github.com/robfig/cron/v3) rather than the system crontab. This approach provides several advantages: Go-native execution, second-level scheduling precision, and safe concurrent job handling within the application process.
The architecture allows multiple independent cron instances across different packages. Each scheduler runs in its own goroutine, ensuring that hardware monitoring tasks never interfere with HTTP request handling or WebSocket communications.
Scheduling Hardware Status Updates
The primary periodic task in CasaOS involves collecting comprehensive hardware metrics and broadcasting them via the internal notification bus.
The Main Scheduler Setup
In main/main.go, the application initializes a global cron instance during startup:
crontab := cron.New(cron.WithSeconds())
if _, err := crontab.AddFunc("@every 5s", route.SendAllHardwareStatusBySocket); err != nil {
logger.Error("add crontab error", zap.Error(err))
}
crontab.Start()
The cron.WithSeconds() option enables second-level precision, while the @every 5s schedule expression ensures the hardware status function executes every five seconds. The Start() method launches the scheduler in a background goroutine immediately.
The Hardware Monitoring Job
The actual data collection logic resides in route/periodical.go within the SendAllHardwareStatusBySocket() function. This job orchestrates system metric gathering through the SystemService interface:
func SendAllHardwareStatusBySocket() {
// 1. Gather network interface statistics
netList := service.MyService.System().GetNetInfo()
// Interface state collection via GetNetState...
// 2. Collect CPU metrics
cpuPercent := service.MyService.System().GetCpuPercent()
cpuCores := service.MyService.System().GetCpuCoreNum()
cpuInfo := service.MyService.System().GetCpuInfo()
cpuTemp := service.MyService.System().GetCPUTemperature()
cpuPower := service.MyService.System().GetCPUPower()
// 3. Retrieve memory statistics
memInfo := service.MyService.System().GetMemInfo()
// 4. Assemble payload
body := map[string]interface{}{
"sys_mem": memInfo,
"sys_cpu": cpuData,
"sys_net": newNet,
}
// 5. Publish to notification bus
service.MyService.Notify().SendNotify("casaos:system:utilization", body)
}
The function aggregates data from multiple sources—including network interfaces via GetNetInfo, processor utilization via GetCpuPercent, and memory statistics via GetMemInfo—then publishes the payload under the topic casaos:system:utilization using the notification service.
Additional Periodic Tasks: WebSocket Heartbeat
CasaOS demonstrates architectural flexibility by allowing sub-packages to maintain their own schedulers. In route/v1/file.go, a separate cron instance manages WebSocket health checks:
func init() {
go handler.monitoring() // Start WebSocket client manager
crontab := cron.New(cron.WithSeconds())
task := func() {
handler.broadcast <- []byte(`{"type":"ping"}`)
}
// Classic cron syntax: every 30 seconds
crontab.AddFunc("*/30 * * * * ?", task)
crontab.Start()
}
This pattern—using */30 * * * * ? cron syntax alongside the @every shorthand—shows that CasaOS supports standard cron expressions with seconds fields. Each independent scheduler handles its own lifecycle, preventing single points of contention.
Key Implementation Details
- Second-level precision: The
cron.WithSeconds()configuration option enables sub-minute scheduling, critical for real-time hardware monitoring. - Goroutine isolation: Each
crontab.Start()invocation spawns a separate goroutine, ensuring periodic tasks never block the main application thread. - Service layer integration: Jobs interact with hardware through the
service.System()interface, abstracting direct system calls into testable service methods. - Notification bus: Rather than tightly coupling to WebSocket handlers, the system uses
service.MyService.Notify().SendNotify()for decoupled message distribution.
Summary
- CasaOS uses the
robfig/cronlibrary for in-process task scheduling with second-level precision. - The main hardware status job runs every 5 seconds via
@every 5sschedule inmain/main.go. route/periodical.gocontainsSendAllHardwareStatusBySocket(), which gathers CPU, memory, network, and temperature data throughSystemServicemethods.- Multiple independent cron instances (e.g., in
route/v1/file.go) allow fine-grained scheduling without contention. - Hardware metrics are published to the
casaos:system:utilizationtopic via the notification bus for decoupled consumption.
Frequently Asked Questions
How does CasaOS prevent periodic tasks from blocking the main application?
CasaOS runs each cron scheduler in its own goroutine. When crontab.Start() is called, the library spawns a background goroutine that sleeps until the next scheduled execution time, leaving the main HTTP server and other services unblocked.
What cron library does CasaOS use for background jobs?
CasaOS uses github.com/robfig/cron/v3, a popular Go library that provides robust cron expression parsing, second-level precision, and thread-safe job execution. This replaces traditional system-level cron for in-application scheduling.
How often does CasaOS send hardware status updates?
According to the source code in main/main.go, CasaOS sends hardware status updates every 5 seconds using the @every 5s schedule expression. This provides near real-time monitoring of CPU, memory, and network utilization.
Where does CasaOS publish the collected hardware status data?
The SendAllHardwareStatusBySocket() function in route/periodical.go publishes data to the internal notification bus using service.MyService.Notify().SendNotify() with the topic casaos:system:utilization, allowing WebSocket handlers and other subscribers to receive updates without direct coupling to the monitoring logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →