adjusted the error handling around auto fragment creation logic

This commit is contained in:
travisturner 2014-06-25 11:26:58 -05:00
parent 41bbff06b6
commit f0a3ad15de
5 changed files with 63 additions and 30 deletions

View file

@ -8,7 +8,6 @@ import (
"sync"
"launchpad.net/goyaml"
)
type Config struct {
@ -41,13 +40,13 @@ func GetString(key string) string {
}
func GetStringArray(key string) []string {
res,_:= config.GetStringArray(key)
res, _ := config.GetStringArray(key)
return res
}
func GetStringArrayDefault(key string,def []string) []string {
res,ok := config.GetStringArray(key)
func GetStringArrayDefault(key string, def []string) []string {
res, ok := config.GetStringArray(key)
if ! ok{
if !ok {
return def
}
return res
@ -61,7 +60,6 @@ func GetIntDefault(key string, default_value int) int {
return config.GetIntDefault(key, default_value)
}
func NewConfig(filename string) *Config {
self := Config{}
self.config = make(map[string]interface{})
@ -85,13 +83,11 @@ func (self *Config) load() error {
}
data, err := ioutil.ReadFile(config_file)
if err != nil {
return errors.New("Problem with config file: " + err.Error())
}
err=goyaml.Unmarshal(data, self.config)
if err != nil{
println(err.Error())
err = goyaml.Unmarshal(data, self.config)
if err != nil {
println(err.Error())
}
self.loaded = true
@ -134,7 +130,6 @@ func (self *Config) GetIntDefault(key string, default_value int) int {
return default_value
}
func (self *Config) GetStringDefault(key string, default_value string) string {
value, ok := self.GetSafe(key)
if ok {
@ -146,7 +141,6 @@ func (self *Config) GetStringDefault(key string, default_value string) string {
return default_value
}
func (self *Config) GetString(key string) string {
value, ok := self.GetSafe(key)
if ok {
@ -158,18 +152,14 @@ func (self *Config) GetString(key string) string {
return ""
}
func (self *Config) GetStringArray(key string) ([]string,bool){
func (self *Config) GetStringArray(key string) ([]string, bool) {
value, ok := self.GetSafe(key)
if ok {
var results []string
for _,v:= range value.([]interface{}){
results=append(results,v.(string))
for _, v := range value.([]interface{}) {
results = append(results, v.(string))
}
return results,ok
return results, ok
}
return []string{},ok
return []string{}, ok
}

View file

@ -105,7 +105,7 @@ func getLightestProcess(m map[string]int) (Pair, error) {
}
func (self *TopologyMapper) MakeFragments(db string, slice_int int) error {
frames_to_create := config.GetStringArrayDefault("supported_frames", []string{"b.n", "l.n", "t.t", "d"})
frames_to_create := config.GetStringArrayDefault("supported_frames", []string{"default"})
for _, frame := range frames_to_create {
err := self.AllocateFragment(db, frame, slice_int)
if err != nil {

View file

@ -4,13 +4,14 @@ import (
"errors"
"fmt"
"log"
"pilosa/config"
"pilosa/util"
"sync"
"github.com/stathat/consistent"
)
var FrameDoesNotExistError = errors.New("Frame does not exist.")
var InvalidFrameError = errors.New("Invalid frame.")
var SliceDoesNotExistError = errors.New("Slice does not exist.")
var FragmentDoesNotExistError = errors.New("Fragment does not exist.")
var FrameSliceIntersectDoesNotExistError = errors.New("FrameSliceIntersect does not exist.")
@ -159,6 +160,20 @@ func (c *Cluster) GetOrCreateDatabase(name string) *Database {
return c.addDatabase(name)
}
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
func (d *Database) IsValidFrame(name string) bool {
supported_frames := config.GetStringArrayDefault("supported_frames", []string{"default"})
return stringInSlice(name, supported_frames)
}
// Count the number of slices in a database
func (d *Database) NumSlices() (int, error) {
if len(d.slices) < 1 {
@ -177,6 +192,10 @@ type Frame struct {
// Get a frame from a database
func (d *Database) getFrame(name string) (*Frame, error) {
// should we check here for supported frames?
if !d.IsValidFrame(name) {
return nil, InvalidFrameError
}
for _, frame := range d.frames {
if frame.name == name {
return frame, nil

View file

@ -73,8 +73,9 @@ func (self *Executor) runQuery(database *db.Database, qry *query.Query) error {
query_plan, err := query.QueryPlanForQuery(database, qry, &destination)
if err != nil {
obj, found := err.(*query.FragmentNotFound)
if found {
switch obj := err.(type) {
//case *query.InvalidFrame:
case *query.FragmentNotFound:
self.service.TopologyMapper.MakeFragments(obj.Db, obj.Slice)
}
self.service.Hold.Set(qry.Id, err, 30)

View file

@ -17,6 +17,26 @@ type PortableQueryStep interface {
GetLocation() *db.Location
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// ERRORS
///////////////////////////////////////////////////////////////////////////////////////////////////
// Invalid Frame
type InvalidFrame struct {
Db string
Frame string
Retry bool
}
func NewInvalidFrame(db string, frame string) *InvalidFrame {
return &InvalidFrame{db, frame, false}
}
func (self *InvalidFrame) Error() string {
return fmt.Sprintf("Invalid Frame: %s:%s", self.Db, self.Frame)
}
// Fragment Not Found
type FragmentNotFound struct {
Db string
Frame string
@ -24,7 +44,7 @@ type FragmentNotFound struct {
Retry bool
}
func NewFragmentNotFound(db, frame string, slice int) *FragmentNotFound {
func NewFragmentNotFound(db string, frame string, slice int) *FragmentNotFound {
return &FragmentNotFound{db, frame, slice, true}
}
@ -269,15 +289,18 @@ type SetQueryTree struct {
// Uses consistent hashing function to select node containing data for GET operation
func (qt *SetQueryTree) getLocation(d *db.Database) (*db.Location, error) {
// check here for supported frames
if !d.IsValidFrame(qt.bitmap.FrameType) {
return nil, NewInvalidFrame(d.Name, qt.bitmap.FrameType)
}
slice, err := d.GetSliceForProfile(qt.profile_id)
if err != nil {
//I should check GetFragmentForBitmap for possible errors but for now i'll just hardcode
return nil, NewFragmentNotFound(d.Name, "b.n", db.GetSlice(qt.profile_id))
return nil, NewFragmentNotFound(d.Name, qt.bitmap.FrameType, db.GetSlice(qt.profile_id))
}
fragment, err := d.GetFragmentForBitmap(slice, qt.bitmap)
if err != nil {
log.Println("NOT FOUND:", slice, qt.bitmap)
return nil, err
return nil, NewFragmentNotFound(d.Name, qt.bitmap.FrameType, db.GetSlice(qt.profile_id))
}
return fragment.GetLocation(), nil
}