Skip to content

Instantly share code, notes, and snippets.

@ian-kent
Created January 31, 2017 22:42
Show Gist options
  • Save ian-kent/bcdcaf1dc71fb6ee78edf475d0dde49e to your computer and use it in GitHub Desktop.
Save ian-kent/bcdcaf1dc71fb6ee78edf475d0dde49e to your computer and use it in GitHub Desktop.
event stuff
package main
/*
// list of events
curl localhost:8080/events
// current state
curl localhost:8080/state
// increment counter
curl -d '{"name": "increment", "data": {"n": 1}}' localhost:8080/event
// decrement counter
curl -d '{"name": "decrement", "data": {"n": 1}}' localhost:8080/event
// set counter
curl -d '{"name": "set", "data": {"n": 1}}' localhost:8080/event
// collapse state into single event
curl -X POST localhost:8080/collapse
*/
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"strconv"
"github.com/gorilla/pat"
)
var state struct {
Counter int `json:"counter"`
}
type event struct {
Name string `json:"name"`
Data map[string]interface{} `json:"data"`
}
var events = make([]event, 0)
func main() {
p := pat.New()
p.Get("/events", eventsHandler)
p.Post("/event", eventHandler)
p.Get("/state", stateHandler)
// p.Post("/collapse", collapseHandler)
p.Get("/", home)
log.Fatal(http.ListenAndServe(":8080", p))
}
func home(w http.ResponseWriter, req *http.Request) {
w.Write([]byte(htmlPage))
}
// func collapseHandler(w http.ResponseWriter, req *http.Request) {
// events = []event{
// event{"set", map[string]interface{}{"n": state.Counter}},
// }
// }
func stateHandler(w http.ResponseWriter, req *http.Request) {
b, _ := json.Marshal(state)
w.Write(b)
}
func eventsHandler(w http.ResponseWriter, req *http.Request) {
var since int
s := req.URL.Query().Get("since")
if len(s) > 0 {
since, _ = strconv.Atoi(s)
}
b, _ := json.Marshal(events[since:])
w.Write(b)
}
func eventHandler(w http.ResponseWriter, req *http.Request) {
b, _ := ioutil.ReadAll(req.Body)
req.Body.Close()
var e event
json.Unmarshal(b, &e)
events = append(events, e)
switch e.Name {
case "set":
n := e.Data["n"].(float64)
state.Counter = int(n)
case "increment":
n := e.Data["n"].(float64)
state.Counter += int(n)
case "decrement":
n := e.Data["n"].(float64)
state.Counter -= int(n)
default:
w.WriteHeader(400)
}
}
var htmlPage = `
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
var state = {
position: 0,
count: 0
};
$(document).ready(function() {
$("#increment").click(function() {
$.post("/event", JSON.stringify({
"name": "increment",
"data": {
"n": 1
}
}));
});
$("#decrement").click(function() {
$.post("/event", JSON.stringify({
"name": "decrement",
"data": {
"n": 1
}
}));
});
setInterval(function() {
$.get("/events?since="+state.position, function(data) {
data = JSON.parse(data);
state.position += data.length;
$.each(data, function(i, v) {
console.log(v);
switch(v.name) {
case "increment":
state.count += v.data.n;
break;
case "decrement":
state.count -= v.data.n;
break;
case "set":
state.count = v.data.n;
break;
}
});
$('#count').text(state.count);
});
}, 1000);
});
</script>
</head>
<body>
<p>
<strong>Count:</strong> <span id="count">0</span>
</p>
<div>
<button id="increment">Increment</button>
<button id="decrement">Decrement</button>
</div>
</body>
</html>
`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment