Skip to content

Commit

Permalink
Fix rate limit custom number
Browse files Browse the repository at this point in the history
  • Loading branch information
gandarez committed Jan 6, 2025
1 parent 92addb5 commit ce559c9
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 19 deletions.
22 changes: 16 additions & 6 deletions cmd/params/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/wakatime/wakatime-cli/pkg/heartbeat"
"github.com/wakatime/wakatime-cli/pkg/ini"
"github.com/wakatime/wakatime-cli/pkg/log"
"github.com/wakatime/wakatime-cli/pkg/offline"
"github.com/wakatime/wakatime-cli/pkg/output"
"github.com/wakatime/wakatime-cli/pkg/project"
"github.com/wakatime/wakatime-cli/pkg/regex"
Expand Down Expand Up @@ -658,17 +659,26 @@ func LoadOfflineParams(ctx context.Context, v *viper.Viper) Offline {

logger := log.Extract(ctx)

rateLimit, _ := vipertools.FirstNonEmptyInt(v, "heartbeat-rate-limit-seconds", "settings.heartbeat_rate_limit_seconds")
if rateLimit < 0 {
logger.Warnf("argument --heartbeat-rate-limit-seconds must be zero or a positive integer number, got %d", rateLimit)
rateLimit := offline.RateLimitDefaultSeconds

rateLimit = 0
if rateLimitSecs, ok := vipertools.FirstNonEmptyInt(v,
"heartbeat-rate-limit-seconds",
"settings.heartbeat_rate_limit_seconds"); ok {
rateLimit = rateLimitSecs

if rateLimit < 0 {
logger.Warnf(
"argument --heartbeat-rate-limit-seconds must be zero or a positive integer number, got %d",
rateLimit,
)

rateLimit = 0
}
}

syncMax := v.GetInt("sync-offline-activity")
if syncMax < 0 {
logger.Warnf("argument --sync-offline-activity must be zero or a positive integer number, got %d", syncMax)

syncMax = 0
}

Expand Down Expand Up @@ -1100,7 +1110,7 @@ func (p Offline) String() string {
}

return fmt.Sprintf(
"disabled: %t, last sent at: '%s', print max: %d, num rate limit: %d, num sync max: %d",
"disabled: %t, last sent at: '%s', print max: %d, rate limit: %s, num sync max: %d",
p.Disabled,
lastSentAt,
p.PrintMax,
Expand Down
17 changes: 9 additions & 8 deletions cmd/params/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import (
"github.com/wakatime/wakatime-cli/pkg/heartbeat"
inipkg "github.com/wakatime/wakatime-cli/pkg/ini"
"github.com/wakatime/wakatime-cli/pkg/log"
"github.com/wakatime/wakatime-cli/pkg/offline"
"github.com/wakatime/wakatime-cli/pkg/output"
"github.com/wakatime/wakatime-cli/pkg/project"
"github.com/wakatime/wakatime-cli/pkg/regex"
"gopkg.in/ini.v1"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/ini.v1"
)

func TestLoadHeartbeatParams_AlternateProject(t *testing.T) {
Expand Down Expand Up @@ -1832,7 +1833,7 @@ func TestLoadOfflineParams_RateLimit_FromConfig(t *testing.T) {

func TestLoadOfflineParams_RateLimit_Zero(t *testing.T) {
v := viper.New()
v.Set("heartbeat-rate-limit-seconds", "0")
v.Set("heartbeat-rate-limit-seconds", 0)

params := cmdparams.LoadOfflineParams(context.Background(), v)

Expand All @@ -1841,11 +1842,11 @@ func TestLoadOfflineParams_RateLimit_Zero(t *testing.T) {

func TestLoadOfflineParams_RateLimit_Default(t *testing.T) {
v := viper.New()
v.SetDefault("heartbeat-rate-limit-seconds", 20)
v.SetDefault("heartbeat-rate-limit-seconds", offline.RateLimitDefaultSeconds)

params := cmdparams.LoadOfflineParams(context.Background(), v)

assert.Equal(t, time.Duration(20)*time.Second, params.RateLimit)
assert.Equal(t, time.Duration(offline.RateLimitDefaultSeconds)*time.Second, params.RateLimit)
}

func TestLoadOfflineParams_RateLimit_NegativeNumber(t *testing.T) {
Expand All @@ -1863,7 +1864,7 @@ func TestLoadOfflineParams_RateLimit_NonIntegerValue(t *testing.T) {

params := cmdparams.LoadOfflineParams(context.Background(), v)

assert.Zero(t, params.RateLimit)
assert.Equal(t, time.Duration(offline.RateLimitDefaultSeconds)*time.Second, params.RateLimit)
}

func TestLoadOfflineParams_LastSentAt(t *testing.T) {
Expand All @@ -1889,7 +1890,7 @@ func TestLoadOfflineParams_LastSentAt_Err(t *testing.T) {

func TestLoadOfflineParams_LastSentAtFuture(t *testing.T) {
v := viper.New()
lastSentAt := time.Now().Add(time.Duration(2) * time.Hour)
lastSentAt := time.Now().Add(2 * time.Hour)
v.Set("internal.heartbeats_last_sent_at", lastSentAt.Format(inipkg.DateFormat))

params := cmdparams.LoadOfflineParams(context.Background(), v)
Expand Down Expand Up @@ -2658,14 +2659,14 @@ func TestOffline_String(t *testing.T) {
Disabled: true,
LastSentAt: lastSentAt,
PrintMax: 6,
RateLimit: 15,
RateLimit: time.Duration(15) * time.Second,
SyncMax: 12,
}

assert.Equal(
t,
"disabled: true, last sent at: '2021-08-30T18:50:42-03:00', print max: 6,"+
" num rate limit: 15, num sync max: 12",
" rate limit: 15s, num sync max: 12",
offline.String(),
)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func setFlags(cmd *cobra.Command, v *viper.Viper) {
"heartbeat-rate-limit-seconds",
offline.RateLimitDefaultSeconds,
fmt.Sprintf("Only sync heartbeats to the API once per these seconds, instead"+
" saving to the offline db. Defaults to %d. Use zero to disable.",
" saving to the offline db. Defaults to %d. Use 0 to disable.",

Check warning on line 131 in cmd/root.go

View check run for this annotation

Codecov / codecov/patch

cmd/root.go#L131

Added line #L131 was not covered by tests
offline.RateLimitDefaultSeconds),
)
flags.String("hide-branch-names", "", "Obfuscate branch names. Will not send revision control branch names to api.")
Expand Down
4 changes: 4 additions & 0 deletions cmd/run_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,10 @@ func TestParseConfigFiles(t *testing.T) {
assert.Equal(t,
"2006-01-02T15:04:05Z07:00",
v.GetString("internal.backoff_at"))
assert.Equal(t,
"2025-01-05T22:21:51Z03:00",
v.GetString("internal.heartbeats_last_sent_at"),
)
}

func TestParseConfigFiles_MissingAPIKey(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions cmd/testdata/.wakatime-internal.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[internal]
backoff_retries = 1
backoff_at = 2006-01-02T15:04:05Z07:00
heartbeats_last_sent_at = 2025-01-05T22:21:51Z03:00
1 change: 0 additions & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ func TestSendHeartbeats_ExtraHeartbeats_SyncLegacyOfflineActivity(t *testing.T)
"--offline-queue-file-legacy", offlineQueueFileLegacy.Name(),
"--lineno", "42",
"--lines-in-file", "100",
"--heartbeat-rate-limit-seconds", "0",
"--time", "1585598059",
"--hide-branch-names", ".*",
"--write",
Expand Down
16 changes: 14 additions & 2 deletions pkg/vipertools/vipertools.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package vipertools
import (
"strings"

"github.com/spf13/cast"
"github.com/spf13/viper"
)

Expand Down Expand Up @@ -31,9 +32,20 @@ func FirstNonEmptyInt(v *viper.Viper, keys ...string) (int, bool) {
}

for _, key := range keys {
if value := v.GetInt(key); value != 0 {
return value, true
if !v.IsSet(key) {
continue
}

// Zero means a valid value when set, so it needs to use generic function and later cast it to int
value := v.Get(key)

// If the value is not an int, it will continue to find the next non-empty key
parsed, err := cast.ToIntE(value)
if err != nil {
continue
}

return parsed, true
}

return 0, false
Expand Down
2 changes: 1 addition & 1 deletion pkg/vipertools/vipertools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestFirstNonEmptyInt_EmptyInt(t *testing.T) {
v := viper.New()
v.Set("first", 0)
_, ok := vipertools.FirstNonEmptyInt(v, "first")
assert.False(t, ok)
assert.True(t, ok)
}

func TestFirstNonEmptyInt_StringValue(t *testing.T) {
Expand Down

0 comments on commit ce559c9

Please sign in to comment.