Hello all,
I'm currently writing my first "serious" http server application with Go. I would like to make sure that I correctly grasp some of the conceptual implications related with it.
My server is, as far as I can see, basically your standard http.ListenAndServe thing, nothing special.
One of my handlers generates an id whenever there is a POST request to /sessions, like so:
var id int
func generateId() {
id = id + 1
return id
}
func CreateSession(res http.ResponseWriter, req *http.Request) {
io.WriteString(res, strconv.Itoa(generateId()))
}
Now, first I made a mental note along the lines of "guess I need to manage the id generation through a channel in order to avoid a mess when concurrent http requests (== goroutines) access the id closure". But my tests showed that no such problem occured, the session id is incremented correctly no matter how many concurrent http requests I fire at POST /sessions (using ab).
Now my mental model is that id = id + 1 seems to be atomic - there is no copy of id's value "somewhere" at any time, it is incremented in place. To verify this, I rewrote the code to:
var id int
func generateId() {
curr := id
time.Sleep(1000 * time.Millisecond)
id = curr + 1
return id
}
which, as expected, led to problems, that is, concurrent http requests resulting in concurrent goroutines all accessing "id", incrementing it by 1 from an "old" value that is no longer true.
Is that more or less a correct mental model?
Regards,
Manuel