Skip to content

contrib/go-redis/redis: data race at WithContext function #387

Description

@subroll

i found that this package will raise data race condition if we call WithContext function every time before we call the command function, e.g, Set or Get function.

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"sync"

	goredis "github.com/go-redis/redis"
	"gopkg.in/DataDog/dd-trace-go.v1/contrib/go-redis/redis"
)

func main() {
	closeApp := make(chan struct{})
	redisOpt := &goredis.Options{
		DB:       0,
		Addr:     "localhost:6379",
		Password: "",
	}
	redisClient := redis.NewClient(redisOpt)

	go func() {
		sigint := make(chan os.Signal, 1)
		signal.Notify(sigint, os.Interrupt)
		<-sigint

		if err := redisClient.Close(); err != nil {
			log.Fatal(fmt.Sprintf("error when closing redis client. err: %+v\n", err))
		}
		closeApp <- struct{}{}
	}()

	var wg sync.WaitGroup
	wg.Add(2000)
	for i := 1; i <= 2000; i++ {
		go writeData(&wg, redisClient, i)
	}
	wg.Wait()

	for i := 1; i <= 2000; i++ {
		go fetchData(redisClient, i)
	}

	<-closeApp
	close(closeApp)
}

func writeData(wg *sync.WaitGroup, redisClient *redis.Client, iterationNum int) {
	defer wg.Done()

	key := fmt.Sprintf("test_key:%d", iterationNum)
	val, err := redisClient.WithContext(context.Background()).Set(key, iterationNum, 0).Result()
	if err != nil {
		log.Printf("[write] error while writing data. iteration: %d. err: %+v\n", iterationNum, err)
		return
	}

	log.Printf("[write] iteration: %d. \nkey written: %s\n value written: %d\n value returned: %s\n",
		iterationNum, key, iterationNum, val)
}

func fetchData(redisClient *redis.Client, iterationNum int) {
	key := fmt.Sprintf("test_key:%d", iterationNum)
	val, err := redisClient.WithContext(context.Background()).Get(key).Result()
	if err != nil {
		log.Printf("[read] error while fetching data. iteration: %d. err: %+v\n", iterationNum, err)
		return
	}

	log.Printf("[read] iteration: %d\n key read: %s\n value read: %s", iterationNum, key, val)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    ackapm:ecosystemcontrib/* related feature requests or bugsbugunintended behavior that has to be fixed

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions