mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 09:05:55 +00:00
adjusted the error handling around auto fragment creation logic
This commit is contained in:
parent
41bbff06b6
commit
f0a3ad15de
5 changed files with 63 additions and 30 deletions
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue