Skip to content

Instantly share code, notes, and snippets.

@tleyden
Created November 18, 2013 17:30
Show Gist options
  • Save tleyden/7531816 to your computer and use it in GitHub Desktop.
Save tleyden/7531816 to your computer and use it in GitHub Desktop.
Data race when trying to expose data via http handler
package main
import (
"fmt"
"net/http"
"time"
)
/*
This code contains data races because the updateFooSlice() goroutine
is changing the same *FooSlice as is being served up by the
http handler without any sync protection.
Should a sync.mutex variable be added or is there a slicker way
to expose internal memory structures to an http handler?
How to reproduce:
$ go run -race main.go
$ httpie http://localhost:8080
*/
type Foo struct {
content string
}
type FooSlice []*Foo
func updateFooSlice(fooSlice *FooSlice) {
for {
foo := &Foo{content: "new"}
(*fooSlice)[0] = foo
(*fooSlice)[1] = nil
time.Sleep(time.Second)
}
}
func installHttpHandler(fooSlice *FooSlice) {
handler := func(w http.ResponseWriter, r *http.Request) {
for _, foo := range *fooSlice {
if foo != nil {
fmt.Fprintf(w, "foo: %v ", (*foo).content)
}
}
}
http.HandleFunc("/", handler)
}
func main() {
foo1 := &Foo{content: "hey"}
foo2 := &Foo{content: "yo"}
fooSlice := &FooSlice{foo1, foo2}
installHttpHandler(fooSlice)
go updateFooSlice(fooSlice)
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment