diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-08-21 19:30:58 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2024-08-21 19:30:58 -0400 |
| commit | d9a0fb6435165fd3c6044de9ce8cbb0662fb6628 (patch) | |
| tree | fd20230cb52529531b1e625ecafedb45faba108c /cmd/hdrwtch/execute.go | |
| parent | ed0b9b410b6c0c8478bb3e456d14753a923d06b4 (diff) | |
| download | x-d9a0fb6435165fd3c6044de9ce8cbb0662fb6628.tar.xz x-d9a0fb6435165fd3c6044de9ce8cbb0662fb6628.zip | |
cmd/hdrwtch: make this ready
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/hdrwtch/execute.go')
| -rw-r--r-- | cmd/hdrwtch/execute.go | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/cmd/hdrwtch/execute.go b/cmd/hdrwtch/execute.go index 9cefd51..f6415ee 100644 --- a/cmd/hdrwtch/execute.go +++ b/cmd/hdrwtch/execute.go @@ -3,13 +3,16 @@ package main import ( "context" "fmt" + "log/slog" "net/http" + "runtime" "time" + "golang.org/x/sync/errgroup" "within.website/x/web/useragent" ) -func checkURL(ctx context.Context, probe Probe) (*ProbeResult, error) { +func checkURL(ctx context.Context, probe Probe) *ProbeResult { result := &ProbeResult{ ProbeID: probe.ID, Region: *region, @@ -22,7 +25,7 @@ func checkURL(ctx context.Context, probe Probe) (*ProbeResult, error) { if err != nil { result.Success = false result.Remark = fmt.Sprintf("failed to create request: %v", err) - return result, fmt.Errorf("failed to create request: %w", err) + return result } req.Header.Set("User-Agent", userAgent) @@ -31,17 +34,72 @@ func checkURL(ctx context.Context, probe Probe) (*ProbeResult, error) { if err != nil { result.Success = false result.Remark = fmt.Sprintf("failed to execute request: %v", err) - return result, fmt.Errorf("failed to execute request: %w", err) + return result } defer resp.Body.Close() result.Success = true result.StatusCode = resp.StatusCode result.Duration = time.Since(start) + result.LastModified = resp.Header.Get("Last-Modified") - return &ProbeResult{ - ProbeID: probe.ID, - StatusCode: resp.StatusCode, - Duration: time.Since(start), - }, nil + return result +} + +func (s *Server) cron() { + ctx, cancel := context.WithTimeout(context.Background(), 14*time.Minute) // 1 minute less than the cron interval + defer cancel() + + tx := s.dao.db.Begin().WithContext(ctx) + defer tx.Rollback() + + var probes []Probe + + if err := s.dao.db.Preload("LastResult").Find(&probes).Error; err != nil { + slog.Error("failed to get probes", "err", err) + return + } + + g, gCtx := errgroup.WithContext(ctx) + g.SetLimit(runtime.NumCPU()) + + for _, probe := range probes { + probe := probe + + g.Go(func() error { + result := checkURL(gCtx, probe) + + if result.LastModified != probe.LastResult.LastModified { + slog.Info("probe result changed", "probe", probe.ID, "old", probe.LastResult, "new", result) + + user, err := s.dao.GetUser(gCtx, probe.UserID) + if err != nil { + slog.Error("failed to get user", "err", err) + return err + } + + if err := s.messageUser(user, fmt.Sprintf("*%s*:\n\nLast modified: %s\nRegion: %s\nStatus code: %d\nRemark: %s", probe.Name, result.LastModified, result.Region, result.StatusCode, result.Remark)); err != nil { + slog.Error("failed to message user", "err", err) + return err + } + } + + if err := s.dao.CreateProbeResult(gCtx, tx, probe, result); err != nil { + slog.Error("failed to create probe result", "err", err, "probe", probe, "result", result) + return err + } + + return nil + }) + } + + if err := g.Wait(); err != nil { + slog.Error("failed to check probes", "err", err) + } + + if err := tx.Commit().Error; err != nil { + slog.Error("failed to commit transaction", "err", err) + } + + slog.Info("checked probes", "count", len(probes)) } |
