Skip to content
This repository was archived by the owner on Jul 19, 2019. It is now read-only.

Update Go server #30

Closed
wants to merge 2 commits into from
Closed

Update Go server #30

wants to merge 2 commits into from

Conversation

zpao
Copy link
Member

@zpao zpao commented Feb 12, 2015

Follow up to #29. cc @freeformz

This does a couple things, mostly to bring the Go server in line with our other servers.

  • 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 response to POST requests

This is the first Go I've ever written so any feedback is welcome.

zpao added 2 commits February 11, 2015 16:15
- 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, "", " ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 problems here:

  1. The use of var encodedComment... vs encodedComments :=
  2. ignoring the error is bad.
  3. 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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. What's the difference? (I totally missed that)
  2. I usually agree. We've been pretty lazy in our other servers but I could handle it.
  3. 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 with Encode. It also felt a bit silly to write the file and then immediately read it (my first pass was to just io.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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 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
}
  1. See above
  2. 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.

Copy link
Member Author

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.

@freeformz
Copy link
Contributor

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.

freeformz pushed a commit to freeformz/react-tutorial that referenced this pull request Feb 26, 2015
Allocate []bytes for reading data in and write out indented JSON.
@freeformz freeformz mentioned this pull request Feb 26, 2015
@zpao zpao closed this in #34 Feb 26, 2015
zpao added a commit that referenced this pull request Feb 26, 2015
@zpao zpao mentioned this pull request Feb 27, 2015
@zpao zpao deleted the more-go branch March 11, 2015 18:40
shenxl pushed a commit to shenxl/react-tutorial that referenced this pull request Sep 15, 2015
Update 11_state-subscriber.js
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants