boulder/test/authz-filler/main.go

107 lines
2.6 KiB
Go

// A quick way to fill up a database with a large number of authz objects, in
// order to manually test the performance of the expired-authz-purger.
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/identifier"
"github.com/letsencrypt/boulder/sa"
)
type fillerConfig struct {
Filler struct {
DB cmd.DBConfig
// TODO(#5275): Remove once all configs in dev, staging and prod
// have been updated to contain the `dbconfig` field
cmd.DeprecatedDBConfig
Parallelism uint
}
}
type model struct {
core.Authorization
LockCol int
}
func main() {
configPath := flag.String("config", "config.json", "Path to Boulder configuration file")
flag.Parse()
configJSON, err := ioutil.ReadFile(*configPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read config file '%s': %s\n", *configPath, err)
os.Exit(1)
}
var config fillerConfig
err = json.Unmarshal(configJSON, &config)
cmd.FailOnError(err, "Failed to parse config")
// TODO(#5275): Remove once all configs in dev, staging and prod
// have been updated to contain the `dbconfig` field
cmd.DefaultDBConfig(&config.Filler.DB, &config.Filler.DeprecatedDBConfig)
// Configure DB
dbURL, err := config.Filler.DB.URL()
cmd.FailOnError(err, "Couldn't load DB URL")
// Set max connections equal to parallelism.
dbSettings := sa.DbSettings{
MaxOpenConns: int(config.Filler.Parallelism),
}
dbMap, err := sa.NewDbMap(dbURL, dbSettings)
cmd.FailOnError(err, "Could not connect to database")
dbMap.AddTableWithName(model{}, "pendingAuthorizations").SetKeys(false, "ID")
span := 24 * time.Hour * 365
start := time.Now().Add(-span)
increment := time.Hour
// Use a buffer with Parallelism entries so there's always work available.
work := make(chan time.Time, config.Filler.Parallelism)
go func() {
for i := 0; i < int(span)/int(increment); i++ {
expires := start.Add(time.Duration(i) * increment)
// Arbitrarily make 30k entries per time chunk.
for j := 0; j < 30000; j++ {
work <- expires
}
}
}()
for i := 0; i < int(config.Filler.Parallelism); i++ {
go func() {
for expires := range work {
err = dbMap.Insert(&model{
core.Authorization{
ID: core.NewToken(),
RegistrationID: 1,
Expires: &expires,
Combinations: [][]int{{1, 2, 3}},
Status: "pending",
Identifier: identifier.ACMEIdentifier{
Type: "dns",
Value: "example.com",
},
},
0,
})
if err != nil {
log.Print(err)
}
}
}()
}
// Block forever.
select {}
}