storj/satellite/reputation/writecache_unit_test.go
paul cannon 799b159bba satellite/reputation: offset write times by random, not by satelliteID
In an effort to distribute load on the reputation database, the
reputation write cache scheduled nodes to be written at a time offset by
the local nodeID. The idea was that no two repair workers would have the
same nodeID, so they would not tend to write to the same row at the same
time.

Instead, since all satellite processes share the same satellite ID
(duh), this caused _all_ workers to try and write to the same row at the
same time _always_. This was not ideal.

This change uses a random number instead of the satellite ID. The random
number is sourced from the number of nanoseconds since the Unix epoch.
As long as workers are not started at the exact same nanosecond, they
ought to get well-distributed offsets.

Change-Id: I149bdaa6ca1ee6043cfedcf1489dd9d3e3c7a163
2022-08-03 21:14:06 +00:00

58 lines
1.8 KiB
Go

// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
package reputation
import (
"encoding/binary"
"testing"
"time"
"github.com/stretchr/testify/require"
"storj.io/common/storj"
)
func TestNextTimeForSync(t *testing.T) {
var zeroesID storj.NodeID
binary.BigEndian.PutUint64(zeroesID[:8], 0) // unnecessary, but for clarity
var halfwayID storj.NodeID
binary.BigEndian.PutUint64(halfwayID[:8], 1<<63)
var quarterwayID storj.NodeID
binary.BigEndian.PutUint64(quarterwayID[:8], 1<<62)
const (
zeroOffset = 0
halfwayOffset = 1 << 63
quarterwayOffset = 1 << 62
)
startOfHour := time.Now().Truncate(time.Hour)
now := startOfHour.Add(15 * time.Minute)
nextTime := nextTimeForSync(zeroOffset, halfwayID, now, time.Hour)
requireInDeltaTime(t, startOfHour.Add(30*time.Minute), nextTime, time.Second)
nextTime = nextTimeForSync(halfwayOffset, zeroesID, now, time.Hour)
requireInDeltaTime(t, startOfHour.Add(30*time.Minute), nextTime, time.Second)
nextTime = nextTimeForSync(zeroOffset, zeroesID, now, time.Hour)
requireInDeltaTime(t, startOfHour.Add(time.Hour), nextTime, time.Second)
nextTime = nextTimeForSync(halfwayOffset, halfwayID, now, time.Hour)
requireInDeltaTime(t, startOfHour.Add(time.Hour), nextTime, time.Second)
nextTime = nextTimeForSync(quarterwayOffset, halfwayID, now, time.Hour)
requireInDeltaTime(t, startOfHour.Add(45*time.Minute), nextTime, time.Second)
}
func requireInDeltaTime(t *testing.T, expected time.Time, actual time.Time, delta time.Duration) {
if delta < 0 {
delta = -delta
}
require.Falsef(t, actual.Before(expected.Add(-delta)), "%s is not within %s of %s", actual, delta, expected)
require.Falsef(t, actual.After(expected.Add(delta)), "%s is not within %s of %s", actual, delta, expected)
}