-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Conversation
- Log to stdout when starting the server - Set response content type headers for JSON - Pretty print the JSON when writing to disk - Send the JSON as a resonse to POST requests
commentsEncoder := json.NewEncoder(cFile) | ||
commentsEncoder.Encode(comments) | ||
// Pretty print the JSON, write to file | ||
var encodedComments, _ = json.MarshalIndent(comments, "", " ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 problems here:
- The use of
var encodedComment...
vsencodedComments :=
- ignoring the error is bad.
- This causes the entirety of the encoded data to be stored in ram in encodedComments. The previous solution handled it via streaming readers and writers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- What's the difference? (I totally missed that)
- I usually agree. We've been pretty lazy in our other servers but I could handle it.
- It gets GCed right? It's not a huge deal but I wanted the file pretty-printed (since we talk about manually editing the file in the tutorial). I didn't see how to use
MarshalIndent
withEncode
. It also felt a bit silly to write the file and then immediately read it (my first pass was to justio.Copy(w, cFile)
like in the GET handler).
Like I said, I haven't written Go. If we could get this pedantically idiomatic and keep the JSON formatting that would be awesome! Either way, nobody should be taking these servers and putting them into production ;) , so it's not the end of the world if we don't get it perfect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I don't think you can actually do multiple assignment with var, only :=, but you're throwing away the err so it maybe doesn't matter in this case? change it to be...
encodedComments, err := json.MarshalIndent(comments, "", " ")
if err != nil {
http.Error(w, fmt.Sprintf("Unable to marshal comments to json: %s", err), http.StatusInternalServerError)
return
}
- See above
- So yes, it would be GC'd. But, it's just generally bad practice to use the non streaming version. Since this is an example I'd rather be exemplifying the "right" (some would probably argue it's not), vs the most convenient.
FWIW: The issue with using {Un,}Marhsal is that they read in the entire source and return byte buffers. So, pretend the json file is 50MB in size. So for each post request that would use the Marshal/Unmarshal pair (vs the encoders) the file would need to be read into a []byte, which would be ~50MB. Then you need to UnMarshal that into the []comment, which would be another data structure of ~50 MB modulo JSON, and then another 50MB+ []byte get's created when you MarshalIndent the updated comment back to JSON. So memory usage is ~150MB doing it this way. I haven't run any specific tests, but the pure Encoder/Decoder version of this will use ~50MB total, most of it because we realize the fully constructed []comment.
However this is an example, and ... AFAICT the other examples are doing it by just reading everything into ram / constructing arbitrary sized objects in ram and then the reverse to write data back out. So maybe I'm being too picky about the example?
I'd be happy to submit a pull request that switches everything to using UnMarshal/MarshalIndent instead if you think it's best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you? That would be awesome. I got my fill of writing Go for the time being :D
The servers implementations are by far the least important part of the whole thing here. The variety is intended to make sure anybody can run something without having to muck around too much with installing different thing (eg, shipping just a Go server would be bad). Keeping the behavior consistent across these servers is important to me though because it makes it easier to help people. No saying "oh you're using the Go server and it does things slightly differently... normally you wouldn't have to parse a single long line of JSON in your head".
So if you wouldn't mind doing that, I'd appreciate it. If you wanted to add comments saying that "normally you wouldn't do this, you would just do X, Y, Z" instead, that's totally fine.
Thanks!. I commented on some of the lines. FWIW: I'm mostly pointing out the issue in item 3, because it's non obvious and while I appreciate the simplicity I strived for a somewhat pedantically idiomatic (to me anyway) Go version. |
Allocate []bytes for reading data in and write out indented JSON.
Update 11_state-subscriber.js
Follow up to #29. cc @freeformz
This does a couple things, mostly to bring the Go server in line with our other servers.
This is the first Go I've ever written so any feedback is welcome.