feat(18-05): wire SNMPCollector into Scheduler and main.go

- Add RegisterCollector method to Scheduler for external collector registration
- Initialize ProfileCache with 5-min refresh in main.go
- Initialize CounterCache using existing Redis client
- Create and register SNMPCollector as "snmp" in scheduler
- Start DiscoveryResponder for NATS SNMP device auto-detection
- Existing RouterOS polling path completely unaffected

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-21 19:34:23 -05:00
parent ffd2629ff0
commit b2c0dc7a08
2 changed files with 36 additions and 1 deletions

View File

@@ -22,6 +22,7 @@ import (
"github.com/staack/the-other-dude/poller/internal/config"
"github.com/staack/the-other-dude/poller/internal/observability"
"github.com/staack/the-other-dude/poller/internal/poller"
"github.com/staack/the-other-dude/poller/internal/snmp"
"github.com/staack/the-other-dude/poller/internal/sshrelay"
"github.com/staack/the-other-dude/poller/internal/store"
"github.com/staack/the-other-dude/poller/internal/tunnel"
@@ -267,6 +268,33 @@ func main() {
maxBackoff,
)
// -----------------------------------------------------------------------
// Initialize SNMP components (profile cache, counter cache, collector)
// -----------------------------------------------------------------------
profileCache := snmp.NewProfileCache(deviceStore.Pool(), 5*time.Minute)
if err := profileCache.Load(ctx); err != nil {
slog.Warn("initial SNMP profile cache load failed (SNMP polling will start after first refresh)", "error", err)
}
go profileCache.StartRefresh(ctx)
counterCache := snmp.NewCounterCache(redisClient)
snmpCollector := snmp.NewSNMPCollector(profileCache, credentialCache, counterCache, snmp.DefaultSNMPConfig())
scheduler.RegisterCollector("snmp", snmpCollector)
slog.Info("SNMP collector registered",
"profile_refresh_interval", "5m",
)
// -----------------------------------------------------------------------
// Initialize SNMP discovery responder (NATS request-reply)
// -----------------------------------------------------------------------
discoveryResponder := bus.NewDiscoveryResponder(publisher.Conn())
if err := discoveryResponder.Start(); err != nil {
slog.Error("failed to start SNMP discovery responder", "error", err)
}
defer discoveryResponder.Stop()
slog.Info("starting device scheduler",
"poll_interval", pollInterval,
"refresh_period", refreshPeriod,

View File

@@ -87,12 +87,19 @@ func NewScheduler(
activeDevices: make(map[string]*deviceState),
}
// Register built-in collectors. Future device types (SNMP) register here.
// Register built-in collectors.
s.collectors["routeros"] = NewRouterOSCollector(locker, credentialCache, connTimeout, cmdTimeout, lockTTL)
return s
}
// RegisterCollector adds a named Collector to the scheduler's dispatch map.
// This allows external packages (e.g., SNMP) to register collectors without
// modifying NewScheduler's parameter list.
func (s *Scheduler) RegisterCollector(name string, c Collector) {
s.collectors[name] = c
}
// Run is the main scheduler loop. It:
// 1. Fetches devices from the database.
// 2. Starts goroutines for newly-discovered devices.