Skip to content

Data Race in Connection Pool #141

@dougnd

Description

@dougnd

We've recently been running using the connection pool and discovered a data race. Running the following snippet:

func main() {
	auth := <auth code here>
	pool, err := email.NewPool(
		"<address here>", 4, auth)
	if err != nil {
		panic(fmt.Errorf("failed to create email pool: %v", err))
	}

	var wg sync.WaitGroup
	n := 10
	wg.Add(n)

	for i := 0; i < n; i++ {
		go func() {
			var err error
			err = pool.Send(&email.Email{
				To:   []string{"[email protected]"},
				From: "[email protected]",
				Text: []byte("This is a test"),
			}, time.Second*10)
			if err != nil {
				panic(err)
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

With the Go race detector enabled:

go run -race main.go

Yields error messages like:

==================
WARNING: DATA RACE
Read at 0x00c0000d6028 by goroutine 12:
  github.com/jordan-wright/email.(*Pool).get()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:87 +0xac
  github.com/jordan-wright/email.(*Pool).Send()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:283 +0x95
  main.main.func1()
      /Users/dndawso/repos/emailtest/main.go:80 +0x244

Previous write at 0x00c0000d6028 by goroutine 10:
  github.com/jordan-wright/email.(*Pool).inc()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:155 +0x191
  github.com/jordan-wright/email.(*Pool).makeOne.func1()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:172 +0x3c

Goroutine 12 (running) created at:
  main.main()
      /Users/dndawso/repos/emailtest/main.go:77 +0x205

Goroutine 10 (running) created at:
  github.com/jordan-wright/email.(*Pool).makeOne()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:171 +0x4c
  github.com/jordan-wright/email.(*Pool).get()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:88 +0x34d
  github.com/jordan-wright/email.(*Pool).Send()
      /Users/dndawso/go/pkg/mod/github.com/jordan-wright/[email protected]+incompatible/pool.go:283 +0x95
  main.main.func1()
      /Users/dndawso/repos/emailtest/main.go:80 +0x244
==================

I believe I see the culprit (references to p.created without locking p.mut) and will work on a pull request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions