Bump
This commit is contained in:
		
							parent
							
								
									3adaa805eb
								
							
						
					
					
						commit
						d417fa653f
					
				
							
								
								
									
										18
									
								
								config.go
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								config.go
									
									
									
									
									
								
							@ -1,18 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"flag"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	config struct {
 | 
					 | 
				
			||||||
		storage string
 | 
					 | 
				
			||||||
		port    int
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func setupConfig() {
 | 
					 | 
				
			||||||
	flag.StringVar(&config.storage, "storage", "-", "Kyoto Cabinet storage path (e.g. burlesque.kch#dfunit=8#msiz=512M)")
 | 
					 | 
				
			||||||
	flag.IntVar(&config.port, "port", 4401, "Server HTTP port")
 | 
					 | 
				
			||||||
	flag.Parse()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										43
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								main.go
									
									
									
									
									
								
							@ -1,39 +1,48 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"flag"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/signal"
 | 
						"os/signal"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/KosyanMedia/burlesque/hub"
 | 
				
			||||||
 | 
						"github.com/KosyanMedia/burlesque/storage"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	version = "0.1.3"
 | 
						version = "0.2.0"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handleShutdown() {
 | 
					var (
 | 
				
			||||||
 | 
						theStorage *storage.Storage
 | 
				
			||||||
 | 
						theHub     *hub.Hub
 | 
				
			||||||
 | 
						config     struct {
 | 
				
			||||||
 | 
							storage string
 | 
				
			||||||
 | 
							port    int
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						flag.StringVar(&config.storage, "storage", "-", "Kyoto Cabinet storage path (e.g. burlesque.kch#dfunit=8#msiz=512M)")
 | 
				
			||||||
 | 
						flag.IntVar(&config.port, "port", 4401, "Server HTTP port")
 | 
				
			||||||
 | 
						flag.Parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						theStorage, err := storage.New(config.storage)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						theHub = hub.New(theStorage)
 | 
				
			||||||
	ch := make(chan os.Signal)
 | 
						ch := make(chan os.Signal)
 | 
				
			||||||
	signal.Notify(ch, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGINT)
 | 
						signal.Notify(ch, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGINT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		<-ch
 | 
							<-ch
 | 
				
			||||||
 | 
							theStorage.Close()
 | 
				
			||||||
		saveState()
 | 
					 | 
				
			||||||
		log("State successfully persisted")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		closeStorage()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		log("Stopped")
 | 
					 | 
				
			||||||
		os.Exit(0)
 | 
							os.Exit(0)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	setupConfig()
 | 
					 | 
				
			||||||
	setupLogging()
 | 
						setupLogging()
 | 
				
			||||||
	setupStorage()
 | 
					 | 
				
			||||||
	setupServer()
 | 
					 | 
				
			||||||
	handleShutdown()
 | 
					 | 
				
			||||||
	loadState()
 | 
					 | 
				
			||||||
	go keepStatePersisted()
 | 
					 | 
				
			||||||
	startServer()
 | 
						startServer()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										136
									
								
								server.go
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								server.go
									
									
									
									
									
								
							@ -1,124 +1,110 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"runtime"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/KosyanMedia/burlesque/hub"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func startServer() {
 | 
					func startServer() {
 | 
				
			||||||
	port := fmt.Sprintf(":%d", config.port)
 | 
						http.HandleFunc("/status", statusHandler)
 | 
				
			||||||
	err := http.ListenAndServe(port, nil)
 | 
						http.HandleFunc("/debug", debugHandler)
 | 
				
			||||||
	if err != nil {
 | 
						http.HandleFunc("/publish", pubHandler)
 | 
				
			||||||
 | 
						http.HandleFunc("/subscribe", subHandler)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := http.ListenAndServe(fmt.Sprintf(":%d", config.port), nil); err != nil {
 | 
				
			||||||
		alert(err, "Error starting server on port %d", config.port)
 | 
							alert(err, "Error starting server on port %d", config.port)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func statusHandler(w http.ResponseWriter, r *http.Request) {
 | 
					func statusHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	info := make(map[string]map[string]uint)
 | 
						// info := make(map[string]map[string]uint)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, q := range queues {
 | 
						// for _, q := range queues {
 | 
				
			||||||
		info[q.name] = map[string]uint{
 | 
						// 	info[q.name] = map[string]uint{
 | 
				
			||||||
			"messages":      q.counter.distance(),
 | 
						// 		// "messages":      q.counter.distance(),
 | 
				
			||||||
			"subscriptions": 0,
 | 
						// 		"subscriptions": 0,
 | 
				
			||||||
		}
 | 
						// 	}
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, r := range pool.requests {
 | 
						// for _, r := range pool.requests {
 | 
				
			||||||
		for _, q := range r.queues {
 | 
						// 	for _, q := range r.queues {
 | 
				
			||||||
			info[q]["subscriptions"]++
 | 
						// 		info[q]["subscriptions"]++
 | 
				
			||||||
		}
 | 
						// 	}
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	jsn, _ := json.Marshal(info)
 | 
						// jsn, _ := json.Marshal(info)
 | 
				
			||||||
	w.Write(jsn)
 | 
						// w.Write(jsn)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func debugHandler(w http.ResponseWriter, r *http.Request) {
 | 
					func debugHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	info := make(map[string]interface{})
 | 
						// info := make(map[string]interface{})
 | 
				
			||||||
	info["version"] = version
 | 
						// info["version"] = version
 | 
				
			||||||
	info["goroutines"] = runtime.NumGoroutine()
 | 
						// info["goroutines"] = runtime.NumGoroutine()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s, err := storage.Status()
 | 
						// s, err := storage.Status()
 | 
				
			||||||
	if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
		alert(err, "Failed to get Kyoto Cabinet status")
 | 
						// 	alert(err, "Failed to get Kyoto Cabinet status")
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
	s = s[:len(s)-1] // Removing trailing new line
 | 
						// s = s[:len(s)-1] // Removing trailing new line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ks := make(map[string]interface{})
 | 
						// ks := make(map[string]interface{})
 | 
				
			||||||
	tokens := strings.Split(s, "\n")
 | 
						// tokens := strings.Split(s, "\n")
 | 
				
			||||||
	for _, t := range tokens {
 | 
						// for _, t := range tokens {
 | 
				
			||||||
		tt := strings.Split(t, "\t")
 | 
						// 	tt := strings.Split(t, "\t")
 | 
				
			||||||
		num, err := strconv.Atoi(tt[1])
 | 
						// 	num, err := strconv.Atoi(tt[1])
 | 
				
			||||||
		if err != nil {
 | 
						// 	if err != nil {
 | 
				
			||||||
			ks[tt[0]] = tt[1]
 | 
						// 		ks[tt[0]] = tt[1]
 | 
				
			||||||
		} else {
 | 
						// 	} else {
 | 
				
			||||||
			ks[tt[0]] = num
 | 
						// 		ks[tt[0]] = num
 | 
				
			||||||
		}
 | 
						// 	}
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
	info["kyoto_cabinet"] = ks
 | 
						// info["kyoto_cabinet"] = ks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	jsn, _ := json.Marshal(info)
 | 
						// jsn, _ := json.Marshal(info)
 | 
				
			||||||
	w.Write(jsn)
 | 
						// w.Write(jsn)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func publishHandler(w http.ResponseWriter, r *http.Request) {
 | 
					func pubHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	defer r.Body.Close()
 | 
						defer r.Body.Close()
 | 
				
			||||||
	msg, _ := ioutil.ReadAll(r.Body)
 | 
						msg, _ := ioutil.ReadAll(r.Body)
 | 
				
			||||||
	if len(msg) == 0 {
 | 
						if len(msg) == 0 {
 | 
				
			||||||
		msg = message(r.FormValue("msg"))
 | 
							msg = []byte(r.FormValue("msg"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						queue := r.FormValue("queue")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qname := r.FormValue("queue")
 | 
						if ok := theHub.Pub(queue, msg); ok {
 | 
				
			||||||
	ok := registerPublication(qname, msg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ok {
 | 
					 | 
				
			||||||
		w.Write([]byte("OK"))
 | 
							w.Write([]byte("OK"))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		http.Error(w, "FAIL", 500)
 | 
							http.Error(w, "FAIL", 500)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func subscriptionHandler(w http.ResponseWriter, r *http.Request) {
 | 
					func subHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	rch := make(chan response)
 | 
						result := make(chan hub.Result)
 | 
				
			||||||
	abort := make(chan bool, 1)
 | 
						queues := strings.Split(r.FormValue("queues"), ",")
 | 
				
			||||||
	req := &request{
 | 
						sub := hub.NewSubscription(queues, result)
 | 
				
			||||||
		queues:     strings.Split(r.FormValue("queues"), ","),
 | 
					 | 
				
			||||||
		responseCh: rch,
 | 
					 | 
				
			||||||
		abort:      abort,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	go registerSubscription(req)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	disconnected := w.(http.CloseNotifier).CloseNotify()
 | 
						disconnected := w.(http.CloseNotifier).CloseNotify()
 | 
				
			||||||
	finished := make(chan bool)
 | 
						finished := make(chan struct{})
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-disconnected:
 | 
							case <-disconnected:
 | 
				
			||||||
			close(rch)
 | 
								sub.Close()
 | 
				
			||||||
			abort <- true
 | 
								close(finished)
 | 
				
			||||||
		case <-finished:
 | 
							case <-finished:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		req.purge()
 | 
					 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
						defer sub.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res, ok := <-rch
 | 
						theHub.Sub(sub)
 | 
				
			||||||
	if !ok {
 | 
						res := <-result
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	w.Header().Set("Queue", res.queue)
 | 
						w.Header().Set("Queue", res.Queue)
 | 
				
			||||||
	w.Write(res.message)
 | 
						w.Write(res.Message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	finished <- true
 | 
						finished <- struct{}{}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func setupServer() {
 | 
					 | 
				
			||||||
	http.HandleFunc("/status", statusHandler)
 | 
					 | 
				
			||||||
	http.HandleFunc("/debug", debugHandler)
 | 
					 | 
				
			||||||
	http.HandleFunc("/publish", publishHandler)
 | 
					 | 
				
			||||||
	http.HandleFunc("/subscribe", subscriptionHandler)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user