Simulation initial
This commit is contained in:
parent
dbcef1f229
commit
5da1eb2944
4 changed files with 78 additions and 9 deletions
|
@ -39,6 +39,7 @@ type alerter struct {
|
|||
scorer trending.Scorer[cl.Talkgroup]
|
||||
scores trending.Scores[cl.Talkgroup]
|
||||
lastScore time.Time
|
||||
sim *Simulation
|
||||
}
|
||||
|
||||
type noopAlerter struct{}
|
||||
|
@ -126,7 +127,7 @@ func (as *alerter) startBackfill(ctx context.Context) {
|
|||
now := time.Now()
|
||||
since := now.Add(-24 * time.Hour * time.Duration(as.cfg.LookbackDays))
|
||||
log.Debug().Time("since", since).Msg("starting stats backfill")
|
||||
count, err := as.backfill(ctx, since)
|
||||
count, err := as.backfill(ctx, since, now)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("backfill failed")
|
||||
return
|
||||
|
@ -143,11 +144,11 @@ func (as *alerter) score(ctx context.Context, now time.Time) {
|
|||
sort.Sort(as.scores)
|
||||
}
|
||||
|
||||
func (as *alerter) backfill(ctx context.Context, since time.Time) (count int, err error) {
|
||||
func (as *alerter) backfill(ctx context.Context, since time.Time, until time.Time) (count int, err error) {
|
||||
db := database.FromCtx(ctx)
|
||||
const backfillStatsQuery = `SELECT system, talkgroup, call_date FROM calls WHERE call_date > $1 AND call_date < $2`
|
||||
|
||||
rows, err := db.Query(ctx, backfillStatsQuery, since, timeseries.DefaultClock.Now())
|
||||
rows, err := db.Query(ctx, backfillStatsQuery, since, until)
|
||||
if err != nil {
|
||||
return count, err
|
||||
}
|
||||
|
|
59
pkg/gordio/alerting/simulate.go
Normal file
59
pkg/gordio/alerting/simulate.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package alerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"dynatron.me/x/stillbox/internal/trending"
|
||||
cl "dynatron.me/x/stillbox/pkg/calls"
|
||||
"dynatron.me/x/stillbox/pkg/gordio/config"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type Simulation struct {
|
||||
config.Alerting
|
||||
ScoreStart time.Time `json:"scoreStart"`
|
||||
|
||||
clock offsetClock
|
||||
*alerter `json:"-"`
|
||||
}
|
||||
|
||||
func (s *Simulation) Simulate(ctx context.Context) trending.Scores[cl.Talkgroup] {
|
||||
s.Enable = true
|
||||
s.alerter = New(s.Alerting, WithClock(&s.clock)).(*alerter)
|
||||
s.alerter.sim = s
|
||||
now := time.Now()
|
||||
sinceLookback := now.Add(-24 * time.Hour * time.Duration(s.LookbackDays))
|
||||
|
||||
s.backfill(ctx, sinceLookback, s.ScoreStart)
|
||||
|
||||
for s.clock = offsetClock(now.Sub(s.ScoreStart)); now.After(now.Add(s.clock.Duration())); s.clock += offsetClock(time.Minute) {
|
||||
s.backfill(ctx, s.clock.Now().Add(-1*time.Minute), s.clock.Now())
|
||||
s.scores = s.scorer.Score()
|
||||
}
|
||||
|
||||
s.lastScore = now
|
||||
sort.Sort(s.scores)
|
||||
|
||||
return s.scores
|
||||
}
|
||||
|
||||
func simulateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
s := new(Simulation)
|
||||
err := json.NewDecoder(r.Body).Decode(s)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("simulate decode")
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: sanity check that ScoreStart is not before lookback and lookback is sane
|
||||
|
||||
s.Simulate(ctx)
|
||||
s.tgStats(w, r)
|
||||
}
|
|
@ -60,13 +60,15 @@ func (as *alerter) tgStats(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
renderData := struct {
|
||||
TGs map[calls.Talkgroup]database.GetTalkgroupsByPackedIDsRow
|
||||
Scores trending.Scores[calls.Talkgroup]
|
||||
LastScore time.Time
|
||||
TGs map[calls.Talkgroup]database.GetTalkgroupsByPackedIDsRow
|
||||
Scores trending.Scores[calls.Talkgroup]
|
||||
LastScore time.Time
|
||||
Simulation *Simulation
|
||||
}{
|
||||
TGs: tgMap,
|
||||
Scores: as.scores,
|
||||
LastScore: as.lastScore,
|
||||
TGs: tgMap,
|
||||
Scores: as.scores,
|
||||
LastScore: as.lastScore,
|
||||
Simulation: as.sim,
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
|
|
@ -46,7 +46,14 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="simform">
|
||||
</div>
|
||||
<table>
|
||||
{{ if .Simluation }}
|
||||
<tr>
|
||||
<td colspan="10">Simulating from {{ .Simulation.ScoreStart }} until now</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
<tr>
|
||||
<th>System</th>
|
||||
<th>TG</th>
|
||||
|
|
Loading…
Reference in a new issue