3 import "container/list"
14 type FetchResponse struct {
19 type StoreRequest struct {
21 Messages chan<- []Message
29 // TODO: Monotonic clock
31 func manage_store(store Store) {
32 messages := list.New()
38 case new_message := <-store.Add:
39 messages.PushBack(new_message)
40 for waiter := waiting.Front(); waiter != nil; waiter = waiter.Next() {
41 waiter.Value.(StoreRequest).Messages <- []Message{new_message}
42 close(waiter.Value.(StoreRequest).Messages)
45 if message_count < max_messages {
48 messages.Remove(messages.Front())
50 case request := <-store.Get:
51 if messages.Back() == nil || request.StartTime.After(messages.Back().Value.(Message).Time) {
52 waiting.PushBack(request)
54 start := messages.Back()
56 if messages.Front().Value.(Message).Time.After(request.StartTime) {
57 start = messages.Front()
58 response_size = message_count
60 for start.Prev().Value.(Message).Time.After(request.StartTime) {
65 response_messages := make([]Message, 0, response_size)
66 for m := start; m != nil; m = m.Next() {
67 response_messages = append(response_messages, m.Value.(Message))
69 request.Messages <- response_messages
75 func start_store() Store {
76 store := Store{make(chan Message, 20), make(chan StoreRequest, 20)}
77 go manage_store(store)
81 func start_server(store Store) {
82 http.HandleFunc("/fetch", func(w http.ResponseWriter, r *http.Request) {
84 url_since := r.FormValue("since")
86 err := json.Unmarshal([]byte(url_since), &since)
88 log.Print("fetch: parse since: ", err)
89 w.WriteHeader(http.StatusBadRequest)
90 w.Write([]byte("Could not parse since as date"))
94 messages_from_store := make(chan []Message, 1)
95 store.Get <- StoreRequest{since, messages_from_store}
97 json_encoded, err := json.Marshal(FetchResponse{<-messages_from_store, time.Now()})
99 log.Print("json encode: ", err)
100 w.WriteHeader(http.StatusInternalServerError)
103 w.Header().Add("Content-Type", "application/json")
104 w.Write(json_encoded)
107 http.HandleFunc("/speak", func(w http.ResponseWriter, r *http.Request) {
108 store.Add <- Message{time.Now(), r.FormValue("text")}
111 log.Fatal(http.ListenAndServe(":8080", nil))
115 store := start_store()