Metrics and logs - MongoDB Submission (#43)
Adds MongoDB-backed submission for survey statistics/metrics and introduces MongoDB ObjectID-based participant/task identifiers to support upserts and linking metrics to a participant. It introduces breaking changes to the exsisting json stat and metric files. Delete the old ones Changes: Add internal/storage/MongoStorage and wire pm survey submit / pm start to submit local .pm/*.json files to MongoDB. Extend stats/metrics models to include MongoDB _id / participant_id fields and add participant ID propagation into task metrics. Update app initialization to generate ObjectIDs for new participants and expose GetParticipantID() via StatsService.
This commit is contained in:
@@ -5,10 +5,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/LazyBachelor/LazyPM/cmd/pm/tasks"
|
||||
"github.com/LazyBachelor/LazyPM/internal/commands/survey"
|
||||
"github.com/LazyBachelor/LazyPM/internal/storage"
|
||||
"github.com/LazyBachelor/LazyPM/pkg/task"
|
||||
"github.com/charmbracelet/huh"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -28,6 +31,79 @@ func runStartCmd(cmd *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("application services are not available")
|
||||
}
|
||||
|
||||
if !cmd.Flags().Changed("dev") {
|
||||
var mongoStorage *storage.MongoStorage
|
||||
var continueWithoutSubmitting bool
|
||||
|
||||
for {
|
||||
|
||||
if app.Config.DbUri == "" {
|
||||
cmd.Println("No database URI provided in environment, survey responses will not be submitted.")
|
||||
break
|
||||
}
|
||||
|
||||
db, err := storage.NewMongoStorageInteractive(cmd.Context(), app.Config.DbUri)
|
||||
if err == nil {
|
||||
mongoStorage = db
|
||||
break
|
||||
}
|
||||
|
||||
cmd.Println("Failed to connect to database, survey responses will not be submitted.")
|
||||
|
||||
if err := huh.NewConfirm().
|
||||
Title("Do you want to continue without submitting your responses?").
|
||||
Description("You can fix your database connection and submit your responses later with the submit command.").
|
||||
Value(&continueWithoutSubmitting).
|
||||
WithTheme(huh.ThemeBase16()).
|
||||
RunAccessible(cmd.OutOrStdout(), cmd.InOrStdin()); err != nil {
|
||||
return fmt.Errorf("failed to read user input: %w", err)
|
||||
}
|
||||
|
||||
if continueWithoutSubmitting {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if mongoStorage != nil {
|
||||
cmd.Println("Connected to Database Successfully. Starting survey...")
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
defer mongoStorage.Close()
|
||||
|
||||
ctx := cmd.Context()
|
||||
|
||||
go func() {
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := mongoStorage.SubmitSurveyResponsesCmd(ctx, app.Config.AppDir); err != nil {
|
||||
cmd.Printf("Failed to submit survey responses: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := mongoStorage.SubmitSurveyResponsesCmd(ctx, app.Config.AppDir); err != nil {
|
||||
cmd.Printf("Failed to submit survey responses: %v\n", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := mongoStorage.SubmitSurveyResponsesCmd(context.Background(), app.Config.AppDir); err != nil {
|
||||
cmd.Printf("Failed to submit survey responses on shutdown: %v\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
} else {
|
||||
cmd.Println("Starting survey without database connection. Your responses will not be submitted...")
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
interfaces := initInterfaces()
|
||||
surveyTasks := initTasks(app)
|
||||
|
||||
@@ -49,11 +125,11 @@ func runStartCmd(cmd *cobra.Command, args []string) error {
|
||||
survey.Task: surveyTasks[survey.Task],
|
||||
}
|
||||
}
|
||||
|
||||
if err := newIntroModel().Run(); err != nil {
|
||||
return returnIfUserQuit(err, "failed to run intro")
|
||||
if !cmd.Flags().Changed("dev") {
|
||||
if err := newIntroModel().Run(); err != nil {
|
||||
return returnIfUserQuit(err, "failed to run intro")
|
||||
}
|
||||
}
|
||||
|
||||
if err := taskLoop(cmd.Context(), app, surveyTasks, interfaces); err != nil {
|
||||
return returnIfUserQuit(err, "task loop failed")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user