recur for period

This commit is contained in:
Erik Winter 2025-01-04 08:54:13 +01:00
parent 8539271026
commit c1698a9ec3
4 changed files with 36 additions and 20 deletions

BIN
dist/plannersync vendored

Binary file not shown.

View File

@ -11,6 +11,7 @@ import (
type Recur struct {
repoSync Syncer
repoRecur Recurrer
days int
logger *slog.Logger
}
@ -24,37 +25,50 @@ func NewRecur(repoRecur Recurrer, repoSync Syncer, logger *slog.Logger) *Recur {
return r
}
func (r *Recur) Run(interval time.Duration) {
func (r *Recur) Run(days int, interval time.Duration) {
r.days = days
ticker := time.NewTicker(interval)
for range ticker.C {
if err := r.Recur(); err != nil {
today := item.NewDateFromString(time.Now().Format(item.DateFormat))
last := today.Add(r.days)
if err := r.Recur(last); err != nil {
r.logger.Error("could not recur", "error", err)
}
}
}
func (r *Recur) Recur() error {
r.logger.Info("start looking for recurring items")
today := item.NewDateFromString(time.Now().Format(item.DateFormat))
items, err := r.repoRecur.ShouldRecur(today)
func (r *Recur) Recur(until item.Date) error {
r.logger.Info("start looking for recurring items", "until", until.String())
items, err := r.repoRecur.ShouldRecur(until)
if err != nil {
return err
}
r.logger.Info("found recurring items", "count", len(items))
for _, i := range items {
r.logger.Info("processing recurring item", "id", i.ID)
// spawn instance
newRecurNext := item.FirstRecurAfter(i.Recurrer, i.RecurNext)
newItem := i
newItem.ID = uuid.New().String()
newItem.Date = newRecurNext
newItem.Recurrer = nil
newItem.RecurNext = item.Date{}
if err := r.repoSync.Update(newItem, time.Now()); err != nil {
return err
for {
if newRecurNext.After(until) {
break
}
// spawn instance
newItem := i
newItem.ID = uuid.New().String()
newItem.Date = newRecurNext
newItem.Recurrer = nil
newItem.RecurNext = item.Date{}
if err := r.repoSync.Update(newItem, time.Now()); err != nil {
return err
}
r.logger.Info("spawned instance", "newID", newItem.ID, "date", newItem.Date)
newRecurNext = item.FirstRecurAfter(i.Recurrer, newRecurNext)
}
r.logger.Info("spawned instance", "newID", newItem.ID, "date", newItem.Date)
// update recurrer
i.RecurNext = newRecurNext

View File

@ -14,6 +14,7 @@ func TestRecur(t *testing.T) {
now := time.Now()
today := item.NewDate(2024, 1, 1)
until := today.Add(3)
mem := NewMemory()
rec := NewRecur(mem, mem, slog.New(slog.NewTextHandler(io.Discard, nil)))
@ -33,7 +34,7 @@ func TestRecur(t *testing.T) {
}
// Run recurrence
if err := rec.Recur(); err != nil {
if err := rec.Recur(until); err != nil {
t.Errorf("Recur failed: %v", err)
}
@ -43,14 +44,14 @@ func TestRecur(t *testing.T) {
t.Errorf("failed to get updated items: %v", err)
}
if len(items) != 2 { // Original + new instance
if len(items) != 4 { // Original + 3 new instances
t.Errorf("expected 2 items, got %d", len(items))
}
// Check that RecurNext was updated
recurItems, err := mem.ShouldRecur(today.Add(1))
recurItems, err := mem.ShouldRecur(until.Add(1))
if err != nil {
t.Fatal(err)
t.Errorf("exp nil, got %v", err)
}
if len(recurItems) != 1 {
t.Errorf("expected 1 recur item, got %d", len(recurItems))

View File

@ -19,6 +19,7 @@ var (
dbName = flag.String("dbname", "planner", "database name")
dbUser = flag.String("dbuser", "test", "database user")
dbPassword = flag.String("dbpassword", "test", "database password")
recurDays = flag.Int("recurdays", 8, "amount of days ahead to recur")
)
func main() {
@ -39,7 +40,7 @@ func main() {
"dbUser": *dbUser,
})
recurrer := NewRecur(repo, repo, logger)
go recurrer.Run(6 * time.Hour)
go recurrer.Run(*recurDays, 6*time.Hour)
srv := NewServer(repo, *apiKey, logger)
go http.ListenAndServe(fmt.Sprintf(":%s", *apiPort), srv)