Skip to content

Instantly share code, notes, and snippets.

@matthewdale
Created March 1, 2024 03:50
Show Gist options
  • Save matthewdale/0605c415fb8bcfbafa2fce5518dce2f7 to your computer and use it in GitHub Desktop.
Save matthewdale/0605c415fb8bcfbafa2fce5518dce2f7 to your computer and use it in GitHub Desktop.
Go driver unnecessary retry repro (GODRIVER-3145)
package main
import (
"context"
"fmt"
"regexp"
"strings"
"time"
"github.com/pterm/pterm"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/event"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
var eventRegex = regexp.MustCompile("([a-z0-9])([A-Z])")
const appName = "GODRIVER-3145"
const uri = "mongodb://localhost:27017,localhost:27018,localhost:27019"
func main() {
bgContext := context.Background()
poolMonitor := &event.PoolMonitor{
Event: func(e *event.PoolEvent) {
snake := strings.ToLower(eventRegex.ReplaceAllString(e.Type, "${1}_${2}"))
name := fmt.Sprintf("pool_event.%s", snake)
pterm.Printfln(pterm.Green("Pool Event: %s"), name)
},
}
opts := options.Client()
opts.SetPoolMonitor(poolMonitor)
opts.SetAppName(appName)
opts.ApplyURI(uri)
opts.SetReadPreference(readpref.Primary())
pterm.Printfln(pterm.Blue("Initiating MongoDB Client..."))
client, err := mongo.Connect(bgContext, opts)
if err != nil {
panic(err)
}
err = client.Ping(bgContext, nil)
if err != nil {
panic(err)
}
pterm.Printfln(pterm.Blue("Connected to MongoDB!"))
collection := client.Database("test").Collection("test")
fastTimeoutCtx, fastQueryCancel := context.WithTimeout(bgContext, 3*time.Second)
defer fastQueryCancel()
pterm.Printfln(pterm.Blue("Starting fast Mongo Query"))
res := collection.FindOne(fastTimeoutCtx, bson.M{})
if res.Err() != nil {
pterm.Printfln(pterm.Red("Fast Query Error: %s"), res.Err())
} else {
pterm.Println(pterm.Blue("Fast query was successful"))
}
enableFailpoint()
defer disableFailpoint()
slowManualTimeoutCtx, slowManualQueryCancel := context.WithCancel(bgContext)
go func() {
time.Sleep(1 * time.Second)
pterm.Printfln(pterm.Red("Manually cancelling slow query"))
slowManualQueryCancel()
}()
pterm.Printfln(pterm.Blue("Starting slow/timeout Mongo Query with manual context cancel"))
res = collection.FindOne(slowManualTimeoutCtx, bson.M{"foo": "bar"})
if res.Err() != nil {
pterm.Printfln(pterm.Red("Slow Query Manual Cancel Error: %s"), res.Err())
} else {
pterm.Println(pterm.Blue("Slow query was successful?????"))
}
slowDeadlineExceededCtx, slowDeadlineExceededCancel := context.WithTimeout(bgContext, 3*time.Second)
defer slowDeadlineExceededCancel()
pterm.Printfln(pterm.Blue("Starting slow/timeout Mongo Query with context deadline exceeded"))
res = collection.FindOne(slowDeadlineExceededCtx, bson.M{"foo": "bar"})
if res.Err() != nil {
pterm.Printfln(pterm.Red("Slow Query Deadline Exceeded Error: %s"), res.Err())
} else {
pterm.Println(pterm.Blue("Slow query was successful?????"))
}
// Give time for any more connection pool events to trigger
time.Sleep(5 * time.Second)
pterm.Printfln(pterm.Blue("Closing mongodb client"))
client.Disconnect(bgContext)
}
func enableFailpoint() {
client, err := mongo.Connect(context.Background(), options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer client.Disconnect(context.Background())
failpoint := bson.D{
{"configureFailPoint", "failCommand"},
{"mode", "alwaysOn"},
{"data", bson.D{
{"appName", appName},
{"failCommands", bson.A{"find"}},
{"blockConnection", true},
{"blockTimeMS", 6_000},
}},
}
err = client.Database("admin").RunCommand(context.Background(), failpoint).Err()
if err != nil {
panic(err)
}
}
func disableFailpoint() {
client, err := mongo.Connect(context.Background(), options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer client.Disconnect(context.Background())
err = client.Database("admin").RunCommand(context.Background(), bson.D{
{"configureFailPoint", "failCommand"},
{"mode", "off"},
}).Err()
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment