Created
February 18, 2016 20:43
-
-
Save geokat/61b70f4a115613c8f561 to your computer and use it in GitHub Desktop.
A comment server written in Golang for the FB react.js tutorial
This file contains hidden or 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
| // A comment server for the FB react.js tutorial at: | |
| // https://facebook.github.io/react/docs/tutorial.html | |
| package main | |
| import ( | |
| "encoding/json" | |
| "io/ioutil" | |
| "log" | |
| "net/http" | |
| "strings" | |
| ) | |
| const max = 2048 | |
| var ( | |
| commentsPut = make(chan Comment) | |
| commentsGet = make(chan *[max]Comment) | |
| count int = 0 | |
| ) | |
| type Comment struct { | |
| Id int `json:"id"` | |
| Author string `json:"author"` | |
| Text string `json:"text"` | |
| } | |
| func failOnError(err error, msg string) { | |
| if err != nil { | |
| log.Fatalf("%s: %s", msg, err) | |
| } | |
| } | |
| func initialize() { | |
| var err error | |
| var cs []Comment | |
| jsn, err := ioutil.ReadFile("./comments.json") | |
| failOnError(err, "Failed to read data file") | |
| err = json.Unmarshal(jsn, &cs) | |
| failOnError(err, "Failed to parse data from file") | |
| go commentsProcessor() | |
| for _, c := range cs { | |
| commentsPut <- c | |
| } | |
| } | |
| // commentsProcessor synchronizes access to the comments array. | |
| // | |
| // New comments to be stored come in via the commentsPut | |
| // channel. Existing comments (pointer to the array) are made | |
| // available on the commentsGet channel. Since both operations are | |
| // wrapped in the same select, access to the comments array is | |
| // synchronized. | |
| func commentsProcessor() { | |
| var comments [max]Comment | |
| for { | |
| select { | |
| case c := <-commentsPut: | |
| if count < max { | |
| if c.Id == 0 { | |
| if count == 0 { | |
| c.Id = 0 | |
| } else { | |
| c.Id = comments[count-1].Id + 1 | |
| } | |
| } | |
| comments[count] = c | |
| count++ | |
| } | |
| case commentsGet <- &comments: | |
| } | |
| } | |
| } | |
| func commentsHandler(w http.ResponseWriter, r *http.Request) { | |
| w.Header().Set("Access-Control-Allow-Origin", "*") | |
| w.Header().Set("Content-Type", "application/json; charset=utf-8") | |
| if strings.ToUpper(r.Method) == "POST" { | |
| newComment := Comment{ | |
| Author: r.FormValue("author"), | |
| Text: r.FormValue("text"), | |
| } | |
| commentsPut <- newComment | |
| w.WriteHeader(201) | |
| } | |
| // We fall through to here in case of POST, too (POST requests | |
| // expect a list of comments in return). | |
| cs := <-commentsGet | |
| jsn, err := json.Marshal(cs[:count]) | |
| failOnError(err, "Error serializing comments") | |
| w.Write(jsn) | |
| } | |
| func main() { | |
| initialize() | |
| http.HandleFunc("/api/comments", commentsHandler) | |
| log.Fatal(http.ListenAndServe(":3000", nil)) | |
| } | |
| /* | |
| * Local variables: | |
| * compile-command: "go run comment_server.go": | |
| * End: | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment