This commit is contained in:
Todd Gruben 2016-02-25 15:43:52 -06:00
parent 1aca83a546
commit c60773d33a
5 changed files with 170 additions and 37 deletions

View file

@ -5,9 +5,11 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
"net/http"
"net/url"
"os"
"os/signal"
"os/user"
@ -18,7 +20,9 @@ import (
"time"
"github.com/BurntSushi/toml"
"github.com/gogo/protobuf/proto"
"github.com/umbel/pilosa"
"github.com/umbel/pilosa/internal"
)
// Build holds the build information passed in at compile time.
@ -72,8 +76,10 @@ func main() {
// Main represents the main program execution.
type Main struct {
index *pilosa.Index
ln net.Listener
index *pilosa.Index
ln net.Listener
ticker *time.Ticker
pollingSecs int
// Path to the configuration file.
ConfigPath string
@ -94,7 +100,6 @@ type Main struct {
func NewMain() *Main {
return &Main{
Config: NewConfig(),
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
@ -176,13 +181,84 @@ func (m *Main) Run(args ...string) error {
// Serve HTTP.
go func() { http.Serve(ln, h) }()
//sync up max slice if more than one node
if len(cluster.Nodes) > 1 {
m.ticker = time.NewTicker(time.Second * time.Duration(m.pollingSecs))
go func() {
for range m.ticker.C {
oldmax:= m.index.SliceN()
newmax:=oldmax
for _, node := range cluster.Nodes {
if hostname != node.Host {
newslice,_:=checkMaxSlice(node.Host)
if newslice>newmax{
newmax= newslice
}
}
}
if newmax>oldmax{
m.index.SetMax(newmax)
}
}
}()
}
fmt.Fprintf(m.Stderr, "Listening as http://%s\n", hostname)
return nil
}
func checkMaxSlice(hostport string) (uint64, error) {
// Create HTTP request.
req, err := http.NewRequest("GET", (&url.URL{
Scheme: "http",
Host: hostport,
Path: "/slices/max",
}).String(), nil)
if err != nil {
return 0, err
}
// Require protobuf encoding.
req.Header.Set("Accept", "application/x-protobuf")
req.Header.Set("Content-Type", "application/x-protobuf")
// Send request to remote node.
resp, err := http.DefaultClient.Do(req)
if err != nil {
return 0, err
}
defer resp.Body.Close()
// Read response into buffer.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return 0, err
}
// Check status code.
if resp.StatusCode != http.StatusOK {
return 0, fmt.Errorf("invalid status: code=%d, err=%s", resp.StatusCode, body)
}
// Decode response object.
pb := internal.SliceMaxResponse{}
if err = proto.Unmarshal(body, &pb); err != nil {
return 0, err
}
return *pb.SliceMax, nil
}
// Close shuts down the process.
func (m *Main) Close() error {
if m.ticker != nil {
m.ticker.Stop()
}
if m.ln != nil {
m.ln.Close()
}
@ -200,6 +276,7 @@ func (m *Main) ParseFlags(args []string) error {
fs.SetOutput(m.Stderr)
fs.StringVar(&m.ConfigPath, "config", "", "config path")
fs.StringVar(&m.CPUProfile, "cpuprofile", "", "write cpu profile to file")
fs.IntVar(&m.pollingSecs, "pollingSecs", 60, "number of seconds to poll the cluster for maxslice")
if err := fs.Parse(args); err != nil {
return err
}

View file

@ -73,6 +73,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
default:
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
}
case "/slices/max":
switch r.Method {
case "GET":
h.handleGetSliceMax(w, r)
default:
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
}
case "/version":
h.handleVersion(w, r)
@ -135,6 +142,24 @@ func (h *Handler) handlePostQuery(w http.ResponseWriter, r *http.Request) {
}
}
func (h *Handler) handleGetSliceMax(w http.ResponseWriter, r *http.Request) error {
sm := h.Index.SliceN()
if strings.Contains(r.Header.Get("Accept"), "application/x-protobuf") {
pb := &internal.SliceMaxResponse{
SliceMax: &sm,
}
if buf, err := proto.Marshal(pb); err != nil {
return err
} else if _, err := w.Write(buf); err != nil {
return err
}
return nil
}
resp := map[string]uint64{"SliceMax": sm}
return json.NewEncoder(w).Encode(resp)
}
// readProfiles returns a list of profile objects by id.
func (h *Handler) readProfiles(db *DB, ids []uint64) ([]*Profile, error) {
if db == nil {

View file

@ -9,8 +9,9 @@ import (
// Index represents a container for fragments.
type Index struct {
mu sync.Mutex
path string
mu sync.Mutex
path string
remoteMax uint64
// Databases by name.
dbs map[string]*DB
@ -19,8 +20,9 @@ type Index struct {
// NewIndex returns a new instance of Index.
func NewIndex(path string) *Index {
return &Index{
path: path,
dbs: make(map[string]*DB),
path: path,
dbs: make(map[string]*DB),
remoteMax: 0,
}
}
@ -72,7 +74,7 @@ func (i *Index) SliceN() uint64 {
i.mu.Lock()
defer i.mu.Unlock()
var sliceN uint64
sliceN := i.remoteMax
for _, db := range i.dbs {
if n := db.SliceN(); n > sliceN {
sliceN = n
@ -154,3 +156,8 @@ func (i *Index) CreateFragmentIfNotExists(db, frame string, slice uint64) (*Frag
}
return f.CreateFragmentIfNotExists(slice)
}
func (i *Index) SetMax(newmax uint64) {
i.mu.Lock()
defer i.mu.Unlock()
i.remoteMax = newmax
}

View file

@ -21,6 +21,7 @@ It has these top-level messages:
ImportRequest
ImportResponse
Cache
SliceMaxResponse
*/
package internal
@ -413,6 +414,23 @@ func (m *Cache) GetBitmapIDs() []uint64 {
return nil
}
type SliceMaxResponse struct {
SliceMax *uint64 `protobuf:"varint,1,req,name=SliceMax" json:"SliceMax,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SliceMaxResponse) Reset() { *m = SliceMaxResponse{} }
func (m *SliceMaxResponse) String() string { return proto.CompactTextString(m) }
func (*SliceMaxResponse) ProtoMessage() {}
func (*SliceMaxResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *SliceMaxResponse) GetSliceMax() uint64 {
if m != nil && m.SliceMax != nil {
return *m.SliceMax
}
return 0
}
func init() {
proto.RegisterType((*Bitmap)(nil), "internal.Bitmap")
proto.RegisterType((*Chunk)(nil), "internal.Chunk")
@ -426,36 +444,38 @@ func init() {
proto.RegisterType((*ImportRequest)(nil), "internal.ImportRequest")
proto.RegisterType((*ImportResponse)(nil), "internal.ImportResponse")
proto.RegisterType((*Cache)(nil), "internal.Cache")
proto.RegisterType((*SliceMaxResponse)(nil), "internal.SliceMaxResponse")
}
var fileDescriptor0 = []byte{
// 436 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x92, 0xcf, 0x6e, 0xd4, 0x30,
0x10, 0xc6, 0x95, 0x8d, 0x93, 0x4d, 0x26, 0x24, 0x6d, 0xcd, 0x25, 0x42, 0xaa, 0xa8, 0xdc, 0xcb,
0x8a, 0x43, 0x0f, 0x15, 0x2f, 0xc0, 0x6e, 0x41, 0x54, 0x88, 0xaa, 0xa5, 0xc0, 0x19, 0xab, 0x98,
0x6e, 0x44, 0x62, 0x07, 0xc7, 0x39, 0xf4, 0x65, 0x78, 0x56, 0xc6, 0x7f, 0x92, 0x2e, 0xb0, 0x88,
0x53, 0x94, 0xcf, 0x63, 0x7f, 0xbf, 0xf9, 0x66, 0xa0, 0x6a, 0xa4, 0x11, 0x5a, 0xf2, 0xf6, 0xac,
0xd7, 0xca, 0x28, 0x9a, 0x4d, 0xff, 0xec, 0x2d, 0xa4, 0xeb, 0xc6, 0x74, 0xbc, 0xa7, 0xcf, 0x21,
0xdd, 0x6c, 0x47, 0xf9, 0x7d, 0xa8, 0xa3, 0x93, 0x78, 0x55, 0x9c, 0x1f, 0x9c, 0xcd, 0x97, 0x9c,
0x4e, 0x8f, 0x21, 0x79, 0x65, 0x8c, 0x1e, 0xea, 0x85, 0x3b, 0xaf, 0x1e, 0xcf, 0xad, 0xcc, 0x4e,
0x21, 0xf1, 0x75, 0x05, 0xc4, 0xef, 0xc4, 0x03, 0xbe, 0xb2, 0x58, 0x11, 0x5a, 0x42, 0xf2, 0x99,
0xb7, 0xa3, 0x70, 0x97, 0x08, 0x63, 0x40, 0xae, 0x79, 0xa3, 0xff, 0xaa, 0xd9, 0xa8, 0x51, 0x1a,
0xac, 0xc1, 0x5f, 0xf6, 0x02, 0x62, 0x44, 0xa2, 0x87, 0x90, 0x79, 0xb2, 0xcb, 0x8b, 0x50, 0x77,
0x04, 0xf9, 0xb5, 0x56, 0xdf, 0x9a, 0x56, 0xa0, 0xe4, 0x6b, 0x5f, 0xc2, 0x32, 0x48, 0x14, 0x60,
0x31, 0x57, 0xfe, 0x07, 0xf5, 0x0a, 0x88, 0xfd, 0xee, 0x52, 0xe4, 0xf4, 0x29, 0x14, 0xb7, 0x46,
0x37, 0xf2, 0x7e, 0xe2, 0x8d, 0x50, 0x44, 0xcb, 0x4f, 0x78, 0xd7, 0x4b, 0x31, 0x4a, 0x8e, 0x62,
0xad, 0x54, 0xeb, 0x25, 0x82, 0x52, 0xc6, 0x56, 0xb0, 0xb4, 0xef, 0xbd, 0xc7, 0x14, 0x67, 0xe7,
0x68, 0xaf, 0xb3, 0x82, 0x27, 0x37, 0xa3, 0xd0, 0x0f, 0x1f, 0xc4, 0x8f, 0x51, 0x0c, 0xc6, 0x42,
0x5f, 0xac, 0x03, 0x00, 0xc6, 0xe0, 0xce, 0x5c, 0x6b, 0x39, 0xad, 0x20, 0xbd, 0x6d, 0x9b, 0x3b,
0x31, 0xa0, 0x2f, 0x46, 0x67, 0xf3, 0x08, 0xad, 0x0e, 0xde, 0xd6, 0x92, 0x7c, 0x6c, 0x3a, 0x7c,
0x86, 0x77, 0x7d, 0x9d, 0xa0, 0x14, 0xd3, 0x03, 0x58, 0xde, 0x8c, 0x5c, 0x9a, 0xb1, 0xab, 0x53,
0x14, 0x4a, 0xf6, 0x33, 0x82, 0x32, 0x38, 0x0e, 0xbd, 0x92, 0x83, 0xb0, 0x4d, 0xbf, 0xd6, 0x1a,
0x3d, 0x6d, 0x7f, 0x27, 0xd3, 0xf8, 0x5d, 0xbf, 0xc5, 0xf9, 0xe1, 0x23, 0x6f, 0x58, 0x8b, 0x1c,
0xa2, 0xab, 0xd0, 0x39, 0xf6, 0x66, 0x87, 0x67, 0xed, 0xff, 0xe8, 0xcd, 0xcd, 0xf4, 0x74, 0x07,
0x30, 0x71, 0x15, 0x47, 0x3b, 0x15, 0x61, 0x4a, 0x08, 0xb8, 0xd9, 0x72, 0x79, 0x2f, 0xbe, 0x3a,
0xc0, 0x8c, 0x7d, 0x81, 0xf2, 0xb2, 0xeb, 0x95, 0x36, 0xff, 0x88, 0xe4, 0x8d, 0xe6, 0x9d, 0x08,
0x91, 0xe0, 0xaf, 0x8b, 0x04, 0x79, 0xc2, 0x3e, 0x4c, 0x1b, 0xe2, 0x99, 0x08, 0xc5, 0xdb, 0xf3,
0x8a, 0x78, 0x0a, 0xc2, 0x8e, 0xa1, 0x9a, 0x1c, 0xf6, 0x44, 0xc0, 0x9e, 0xe1, 0xf6, 0xf1, 0xbb,
0xad, 0xf8, 0xfd, 0x39, 0x3b, 0x3e, 0xf2, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x77, 0xe5, 0x8e, 0x3b,
0x38, 0x03, 0x00, 0x00,
// 451 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x92, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0xc7, 0xe5, 0xf8, 0x23, 0xf6, 0x18, 0xbb, 0xe9, 0x72, 0xb1, 0x90, 0x2a, 0xaa, 0x2d, 0x87,
0x88, 0x43, 0x0f, 0x15, 0x2f, 0x40, 0x52, 0x10, 0x15, 0x6a, 0xd5, 0x52, 0xe0, 0xcc, 0xaa, 0x2c,
0x8d, 0x85, 0xbd, 0x6b, 0xd6, 0x6b, 0x89, 0xbe, 0x0c, 0xcf, 0xca, 0xec, 0x87, 0x9d, 0x00, 0x41,
0x3d, 0x59, 0xfe, 0xef, 0xcc, 0xfc, 0x7f, 0xf3, 0x01, 0x65, 0x2d, 0x34, 0x57, 0x82, 0x35, 0xa7,
0x9d, 0x92, 0x5a, 0x92, 0x74, 0xfc, 0xa7, 0xef, 0x20, 0x59, 0xd5, 0xba, 0x65, 0x1d, 0x79, 0x0e,
0xc9, 0x7a, 0x33, 0x88, 0xef, 0x7d, 0x15, 0x1c, 0x87, 0xcb, 0xfc, 0xec, 0xe0, 0x74, 0x4a, 0xb2,
0x3a, 0x39, 0x82, 0xf8, 0xb5, 0xd6, 0xaa, 0xaf, 0x66, 0xf6, 0xbd, 0xdc, 0xbe, 0x1b, 0x99, 0x9e,
0x40, 0xec, 0xe2, 0x72, 0x08, 0xdf, 0xf3, 0x07, 0xac, 0x32, 0x5b, 0x46, 0xa4, 0x80, 0xf8, 0x33,
0x6b, 0x06, 0x6e, 0x93, 0x22, 0x4a, 0x21, 0xba, 0x66, 0xb5, 0xfa, 0x27, 0x66, 0x2d, 0x07, 0xa1,
0x31, 0x06, 0x7f, 0xe9, 0x4b, 0x08, 0x11, 0x89, 0x2c, 0x20, 0x75, 0x64, 0x17, 0xe7, 0x3e, 0xee,
0x10, 0xb2, 0x6b, 0x25, 0xbf, 0xd5, 0x0d, 0x47, 0xc9, 0xc5, 0xbe, 0x82, 0xb9, 0x97, 0x08, 0xc0,
0x6c, 0x8a, 0x7c, 0x04, 0xf5, 0x0a, 0x22, 0xf3, 0xdd, 0xa5, 0xc8, 0xc8, 0x53, 0xc8, 0x6f, 0xb5,
0xaa, 0xc5, 0xfd, 0xc8, 0x1b, 0xa0, 0x88, 0x96, 0x9f, 0x30, 0xd7, 0x49, 0x21, 0x4a, 0x96, 0x62,
0x25, 0x65, 0xe3, 0xa4, 0x08, 0xa5, 0x94, 0x2e, 0x61, 0x6e, 0xea, 0x5d, 0xe2, 0x14, 0x27, 0xe7,
0x60, 0xaf, 0xb3, 0x84, 0x27, 0x37, 0x03, 0x57, 0x0f, 0x1f, 0xf8, 0x8f, 0x81, 0xf7, 0xda, 0x40,
0x9f, 0xaf, 0x3c, 0x00, 0x8e, 0xc1, 0xbe, 0xd9, 0xd6, 0x32, 0x52, 0x42, 0x72, 0xdb, 0xd4, 0x77,
0xbc, 0x47, 0x5f, 0x1c, 0x9d, 0x99, 0x87, 0x6f, 0xb5, 0x77, 0xb6, 0x86, 0xe4, 0x63, 0xdd, 0x62,
0x19, 0xd6, 0x76, 0x55, 0x8c, 0x52, 0x48, 0x0e, 0x60, 0x7e, 0x33, 0x30, 0xa1, 0x87, 0xb6, 0x4a,
0x50, 0x28, 0xe8, 0xaf, 0x00, 0x0a, 0xef, 0xd8, 0x77, 0x52, 0xf4, 0xdc, 0x34, 0xfd, 0x46, 0x29,
0xf4, 0x34, 0xfd, 0x1d, 0x8f, 0xeb, 0xb7, 0xfd, 0xe6, 0x67, 0x8b, 0x2d, 0xaf, 0x3f, 0x8b, 0x0c,
0x82, 0x2b, 0xdf, 0x39, 0xf6, 0x66, 0x96, 0x67, 0xec, 0xff, 0xea, 0xcd, 0xee, 0xf4, 0x64, 0x07,
0x30, 0xb6, 0x11, 0x87, 0x3b, 0x11, 0x7e, 0x4b, 0x08, 0xb8, 0xde, 0x30, 0x71, 0xcf, 0xbf, 0x5a,
0xc0, 0x94, 0x7e, 0x81, 0xe2, 0xa2, 0xed, 0xa4, 0xd2, 0xff, 0x19, 0xc9, 0x5b, 0xc5, 0x5a, 0xee,
0x47, 0x82, 0xbf, 0x76, 0x24, 0xc8, 0xe3, 0xef, 0x61, 0xbc, 0x10, 0xc7, 0x14, 0x11, 0xcc, 0x9e,
0x4e, 0xc4, 0x51, 0x44, 0xf4, 0x08, 0xca, 0xd1, 0x61, 0xcf, 0x08, 0xe8, 0x33, 0xbc, 0x3e, 0x76,
0xb7, 0xe1, 0x7f, 0x96, 0x0b, 0x6c, 0xea, 0x0b, 0x58, 0x58, 0xc3, 0x4b, 0xf6, 0x73, 0x4a, 0xc6,
0x3d, 0x8c, 0x9a, 0xbb, 0xb6, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xf5, 0x8b, 0xab, 0x5e,
0x03, 0x00, 0x00,
}

View file

@ -69,3 +69,7 @@ message ImportResponse {
message Cache {
repeated uint64 BitmapIDs = 1;
}
message SliceMaxResponse {
required uint64 SliceMax = 1;
}