From fa4c0ec82310bb63dbbc56a2c3a123c9526d3761 Mon Sep 17 00:00:00 2001 From: Romain LE JEUNE Date: Tue, 27 Jun 2023 20:16:31 +0200 Subject: [PATCH] feat(GODT-2713): Send config_progress event once a day if the configuration is stucked in pending for more than a day. --- .../configstatus/configuration_progress.go | 39 ++++++++++++++++++- internal/configstatus/types_config_status.go | 2 + internal/user/config_status.go | 29 ++++++++++++++ internal/user/user.go | 8 ++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/internal/configstatus/configuration_progress.go b/internal/configstatus/configuration_progress.go index 6329aa35..37dfd2d8 100644 --- a/internal/configstatus/configuration_progress.go +++ b/internal/configstatus/configuration_progress.go @@ -17,4 +17,41 @@ package configstatus -// GODT-2713 +import "time" + +type ConfigProgressValues struct { + NbDay int `json:"nb_day"` + NbDaySinceLast int `json:"nb_day_since_last"` +} + +type ConfigProgressData struct { + MeasurementGroup string + Event string + Values ConfigProgressValues + Dimensions struct{} +} + +type ConfigProgressBuilder struct{} + +func (*ConfigProgressBuilder) New(data *ConfigurationStatusData) ConfigProgressData { + return ConfigProgressData{ + MeasurementGroup: "bridge.any.configuration", + Event: "bridge_config_progress", + Values: ConfigProgressValues{ + NbDay: numberOfDay(time.Now(), data.DataV1.PendingSince), + NbDaySinceLast: numberOfDay(time.Now(), data.DataV1.LastProgress), + }, + } +} + +func numberOfDay(now, prev time.Time) int { + if now.Year() > prev.Year() { + if now.YearDay() > prev.YearDay() { + return 365 + (now.YearDay() - prev.YearDay()) + } + return (prev.YearDay() + now.YearDay()) - 365 + } else if now.YearDay() > prev.YearDay() { + return now.YearDay() - prev.YearDay() + } + return 0 +} diff --git a/internal/configstatus/types_config_status.go b/internal/configstatus/types_config_status.go index f9188e00..0e9ea9f0 100644 --- a/internal/configstatus/types_config_status.go +++ b/internal/configstatus/types_config_status.go @@ -23,6 +23,8 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/safe" ) +const ProgressCheckInterval = time.Hour + type Metadata struct { Version string `json:"version"` } diff --git a/internal/user/config_status.go b/internal/user/config_status.go index e798d4c5..e77ea16b 100644 --- a/internal/user/config_status.go +++ b/internal/user/config_status.go @@ -82,4 +82,33 @@ func (user *User) SendConfigStatusRecovery() { } func (user *User) SendConfigStatusProgress() { + if !user.telemetryManager.IsTelemetryAvailable() { + return + } + if !user.configStatus.IsPending() { + return + } + + var builder configstatus.ConfigProgressBuilder + progress := builder.New(user.configStatus.Data) + if progress.Values.NbDaySinceLast == 0 || progress.Values.NbDay == 0 { + return + } + + data, err := json.Marshal(progress) + if err != nil { + if err := user.reporter.ReportMessageWithContext("Cannot parse config_progress data.", reporter.Context{ + "error": err, + }); err != nil { + user.log.WithError(err).Error("Failed to report config_progress data parsing error.") + } + return + } + + if err := user.SendTelemetry(context.Background(), data); err == nil { + user.log.Info("Configuration Status Progress event sent.") + if err := user.configStatus.ApplyProgress(); err != nil { + user.log.WithError(err).Error("Failed to ApplyProgress on config_status.") + } + } } diff --git a/internal/user/user.go b/internal/user/user.go index f4799180..2fa2e7bd 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -98,6 +98,8 @@ type User struct { configStatus *configstatus.ConfigurationStatus telemetryManager telemetry.Availability + // goStatusProgress triggers a check/sending if progress is needed. + goStatusProgress func() } // New returns a new user. @@ -176,6 +178,12 @@ func New( telemetryManager: telemetryManager, } + // Check for status_progress when triggered. + user.goStatusProgress = user.tasks.PeriodicOrTrigger(configstatus.ProgressCheckInterval, 0, func(ctx context.Context) { + user.SendConfigStatusProgress() + }) + defer user.goStatusProgress() + // Initialize the user's update channels for its current address mode. user.initUpdateCh(encVault.AddressMode())