Created
November 18, 2013 17:30
-
-
Save tleyden/7531816 to your computer and use it in GitHub Desktop.
Data race when trying to expose data via http handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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