aboutsummaryrefslogtreecommitdiff
path: root/cmd/hdrwtch/execute.go
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-08-21 19:30:58 -0400
committerXe Iaso <me@xeiaso.net>2024-08-21 19:30:58 -0400
commitd9a0fb6435165fd3c6044de9ce8cbb0662fb6628 (patch)
treefd20230cb52529531b1e625ecafedb45faba108c /cmd/hdrwtch/execute.go
parented0b9b410b6c0c8478bb3e456d14753a923d06b4 (diff)
downloadx-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.go74
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))
}