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) {
83 var since time.Time // TODO: Get start time from URL
84 messages_from_store := make(chan []Message, 1)
85 store.Get <- StoreRequest{since, messages_from_store}
87 json_encoded, err := json.Marshal(FetchResponse{<-messages_from_store, time.Now()})
89 log.Print("json encode: ", err)
90 w.WriteHeader(http.StatusInternalServerError)
93 w.Header().Add("Content-Type", "application/json")
97 http.HandleFunc("/speak", func(w http.ResponseWriter, r *http.Request) {
98 text := "woof" // TODO: Get text from URL
99 store.Add <- Message{time.Now(), text}
102 log.Fatal(http.ListenAndServe(":8080", nil))
106 store := start_store()