1
0
Fork 0

Merge remote-tracking branch 'origin' into wal-snapshot-store-v3

master
Philip O'Toole 1 year ago
commit 1a24557c19

@ -20,7 +20,7 @@ When officially released 8.0 will support (mostly) seamless upgrades from the 7.
- [PR #1355](https://github.com/rqlite/rqlite/pull/1355): Database layer can run an integrity check.
- [PR #1385](https://github.com/rqlite/rqlite/pull/1358): Remove support for in-memory databases.
- [PR #1360](https://github.com/rqlite/rqlite/pull/1360): 'go mod' updates, and move to go 1.21.
- [PR #1369](https://github.com/rqlite/rqlite/pull/1369): Use singleton, sync'ed, random source for Store testing.
- [PR #1369](https://github.com/rqlite/rqlite/pull/1369), [PR #1370](https://github.com/rqlite/rqlite/pull/1370): Use singleton, sync'ed, random source.
## 7.21.4 (July 8th 2023)
### Implementation changes and bug fixes

@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"log"
"math/rand"
"net/http"
"os"
"strings"
@ -15,12 +14,9 @@ import (
"time"
rurl "github.com/rqlite/rqlite/http/url"
"github.com/rqlite/rqlite/random"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
var (
// ErrBootTimeout is returned when a boot operation does not
// complete within the timeout.
@ -116,7 +112,7 @@ func (b *Bootstrapper) SetBasicAuth(username, password string) {
func (b *Bootstrapper) Boot(id, raftAddr string, done func() bool, timeout time.Duration) error {
timeoutT := time.NewTimer(timeout)
defer timeoutT.Stop()
tickerT := time.NewTimer(jitter(time.Millisecond))
tickerT := time.NewTimer(random.Jitter(time.Millisecond))
defer tickerT.Stop()
for {
@ -131,7 +127,7 @@ func (b *Bootstrapper) Boot(id, raftAddr string, done func() bool, timeout time.
b.setBootStatus(BootDone)
return nil
}
tickerT.Reset(jitter(b.Interval)) // Move to longer-period polling
tickerT.Reset(random.Jitter(b.Interval)) // Move to longer-period polling
targets, err := b.provider.Lookup()
if err != nil {
@ -255,10 +251,3 @@ func (s *stringAddressProvider) Lookup() ([]string, error) {
func NewAddressProviderString(ss []string) AddressProvider {
return &stringAddressProvider{ss}
}
// jitter adds a little bit of randomness to a given duration. This is
// useful to prevent nodes across the cluster performing certain operations
// all at the same time.
func jitter(duration time.Duration) time.Duration {
return duration + time.Duration(rand.Float64()*float64(duration))
}

@ -10,7 +10,6 @@ import (
"expvar"
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"strconv"
@ -52,7 +51,6 @@ var DBVersion string
var stats *expvar.Map
func init() {
rand.Seed(time.Now().UnixNano())
DBVersion, _, _ = sqlite3.Version()
stats = expvar.NewMap("db")
ResetStats()

@ -4,7 +4,6 @@ import (
"database/sql"
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"sync"
@ -1014,8 +1013,3 @@ func mustFileSize(path string) int64 {
fi := mustStat(path)
return fi.Size()
}
func mustRandomInt(n int) int {
rand.Seed(time.Now().UnixNano())
return rand.Intn(n)
}

@ -3,15 +3,12 @@ package disco
import (
"fmt"
"log"
"math/rand"
"os"
"sync"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
"github.com/rqlite/rqlite/random"
)
const (
leaderChanLen = 5 // Support any fast back-to-back leadership changes.
@ -79,7 +76,7 @@ func (s *Service) Register(id, apiAddr, addr string) (bool, string, error) {
return true, apiAddr, nil
}
time.Sleep(jitter(s.RegisterInterval))
time.Sleep(random.Jitter(s.RegisterInterval))
}
}
@ -141,7 +138,3 @@ func (s *Service) updateContact(t time.Time) {
defer s.mu.Unlock()
s.lastContact = t
}
func jitter(duration time.Duration) time.Duration {
return duration + time.Duration(rand.Float64()*float64(duration))
}

@ -0,0 +1,50 @@
package random
import (
"math/rand"
"strings"
"sync"
"time"
)
var r *rand.Rand
var mu sync.Mutex
func init() {
r = rand.New(rand.NewSource(time.Now().UnixNano()))
}
// RandomString returns a random string of 20 characters
func String() string {
mu.Lock()
defer mu.Unlock()
var output strings.Builder
chars := "abcdedfghijklmnopqrstABCDEFGHIJKLMNOP"
for i := 0; i < 20; i++ {
random := r.Intn(len(chars))
randomChar := chars[random]
output.WriteString(string(randomChar))
}
return output.String()
}
// Float64 returns a random float64
func Float64() float64 {
mu.Lock()
defer mu.Unlock()
return r.Float64()
}
// Intn returns a random int
func Intn(n int) int {
mu.Lock()
defer mu.Unlock()
return r.Intn(n)
}
// Jitter adds a little bit of randomness to a given duration. This is
// useful to prevent nodes across the cluster performing certain operations
// all at the same time.
func Jitter(d time.Duration) time.Duration {
return d + time.Duration(Float64()*float64(d))
}

@ -0,0 +1,51 @@
package random
import (
"testing"
)
func Test_StringLength(t *testing.T) {
str := String()
if len(str) != 20 {
t.Errorf("String() returned a string of length %d; want 20", len(str))
}
}
func Test_StringUniqueness(t *testing.T) {
const numStrings = 10
strs := make(map[string]bool, numStrings)
for i := 0; i < numStrings; i++ {
str := String()
if strs[str] {
t.Errorf("String() returned a non-unique string: %s", str)
}
strs[str] = true
}
}
func Test_Float64Uniqueness(t *testing.T) {
const numFloat64s = 10
floats := make(map[float64]bool, numFloat64s)
for i := 0; i < numFloat64s; i++ {
f := Float64()
if floats[f] {
t.Errorf("Float64() returned a non-unique float64: %f", f)
}
floats[f] = true
}
}
func Test_IntnUniqueness(t *testing.T) {
const numIntns = 10
intns := make(map[int]bool, numIntns)
for i := 0; i < numIntns; i++ {
n := Intn(1000000000)
if intns[n] {
t.Errorf("Intn() returned a non-unique int: %d", n)
}
intns[n] = true
}
}

@ -1,29 +0,0 @@
package random
import (
"math/rand"
"strings"
"sync"
"time"
)
var r *rand.Rand
var mu sync.Mutex
func init() {
r = rand.New(rand.NewSource(time.Now().UnixNano()))
}
// RandomString returns a random string of 20 characters
func RandomString() string {
mu.Lock()
defer mu.Unlock()
var output strings.Builder
chars := "abcdedfghijklmnopqrstABCDEFGHIJKLMNOP"
for i := 0; i < 20; i++ {
random := r.Intn(len(chars))
randomChar := chars[random]
output.WriteString(string(randomChar))
}
return output.String()
}

@ -1,25 +0,0 @@
package random
import (
"testing"
)
func Test_RandomStringLength(t *testing.T) {
str := RandomString()
if len(str) != 20 {
t.Errorf("RandomString() returned a string of length %d; want 20", len(str))
}
}
func Test_RandomStringUniqueness(t *testing.T) {
const numStrings = 100
strs := make(map[string]bool, numStrings)
for i := 0; i < numStrings; i++ {
str := RandomString()
if strs[str] {
t.Errorf("RandomString() returned a non-unique string: %s", str)
}
strs[str] = true
}
}

@ -15,7 +15,7 @@ import (
"github.com/rqlite/rqlite/command"
"github.com/rqlite/rqlite/command/encoding"
"github.com/rqlite/rqlite/db"
"github.com/rqlite/rqlite/store/random"
"github.com/rqlite/rqlite/random"
"github.com/rqlite/rqlite/testdata/chinook"
)
@ -2827,18 +2827,18 @@ func mustNewStoreAtPathsLn(id, dataPath, sqlitePath string, fk bool) (*Store, ne
}
func mustNewStore(t *testing.T) (*Store, net.Listener) {
return mustNewStoreAtPathsLn(random.RandomString(), t.TempDir(), "", false)
return mustNewStoreAtPathsLn(random.String(), t.TempDir(), "", false)
}
func mustNewStoreFK(t *testing.T) (*Store, net.Listener) {
return mustNewStoreAtPathsLn(random.RandomString(), t.TempDir(), "", true)
return mustNewStoreAtPathsLn(random.String(), t.TempDir(), "", true)
}
func mustNewStoreSQLitePath(t *testing.T) (*Store, net.Listener, string) {
dataDir := t.TempDir()
sqliteDir := t.TempDir()
sqlitePath := filepath.Join(sqliteDir, "explicit-path.db")
s, ln := mustNewStoreAtPathsLn(random.RandomString(), dataDir, sqlitePath, true)
s, ln := mustNewStoreAtPathsLn(random.String(), dataDir, sqlitePath, true)
return s, ln, sqlitePath
}

@ -2,11 +2,12 @@ package pool
import (
"log"
"math/rand"
"net"
"sync"
"testing"
"time"
"github.com/rqlite/rqlite/random"
)
var (
@ -21,8 +22,6 @@ func init() {
// used for factory function
go simpleTCPServer()
time.Sleep(time.Millisecond * 300) // wait until tcp server has been settled
rand.Seed(time.Now().UTC().UnixNano())
}
func TestNew(t *testing.T) {
@ -229,7 +228,7 @@ func TestPoolConcurrent2(t *testing.T) {
for i := 0; i < 10; i++ {
go func(i int) {
conn, _ := p.Get()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
time.Sleep(time.Millisecond * time.Duration(random.Intn(100)))
conn.Close()
wg.Done()
}(i)
@ -240,7 +239,7 @@ func TestPoolConcurrent2(t *testing.T) {
wg.Add(1)
go func(i int) {
conn, _ := p.Get()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
time.Sleep(time.Millisecond * time.Duration(random.Intn(100)))
conn.Close()
wg.Done()
}(i)

Loading…
Cancel
Save