Skip to content

Instantly share code, notes, and snippets.

@geokat
Created February 18, 2016 20:43
Show Gist options
  • Select an option

  • Save geokat/61b70f4a115613c8f561 to your computer and use it in GitHub Desktop.

Select an option

Save geokat/61b70f4a115613c8f561 to your computer and use it in GitHub Desktop.
A comment server written in Golang for the FB react.js tutorial
// 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