|
|
|
@ -16,9 +16,12 @@ type Location struct { |
|
|
|
Url string `json:"url,omitempty"` |
|
|
|
PublicUrl string `json:"publicUrl,omitempty"` |
|
|
|
} |
|
|
|
|
|
|
|
type Locations []Location |
|
|
|
|
|
|
|
type LookupResult struct { |
|
|
|
VolumeId string `json:"volumeId,omitempty"` |
|
|
|
Locations []Location `json:"locations,omitempty"` |
|
|
|
Locations Locations `json:"locations,omitempty"` |
|
|
|
Error string `json:"error,omitempty"` |
|
|
|
} |
|
|
|
|
|
|
|
@ -26,11 +29,20 @@ func (lr *LookupResult) String() string { |
|
|
|
return fmt.Sprintf("VolumeId:%s, Locations:%v, Error:%s", lr.VolumeId, lr.Locations, lr.Error) |
|
|
|
} |
|
|
|
|
|
|
|
func (ls Locations) Head() *Location { |
|
|
|
return &ls[0] |
|
|
|
} |
|
|
|
|
|
|
|
func (ls Locations) PickForRead() *Location { |
|
|
|
return &ls[rand.Intn(len(ls))] |
|
|
|
} |
|
|
|
|
|
|
|
var ( |
|
|
|
vc VidCache // caching of volume locations, re-check if after 10 minutes
|
|
|
|
) |
|
|
|
|
|
|
|
func Lookup(server string, vid string) (ret *LookupResult, err error) { |
|
|
|
//Maybe we should fetch from master when lookup location for write
|
|
|
|
locations, cache_err := vc.Get(vid) |
|
|
|
if cache_err != nil { |
|
|
|
if ret, err = do_lookup(server, vid); err == nil { |
|
|
|
@ -60,7 +72,7 @@ func do_lookup(server string, vid string) (*LookupResult, error) { |
|
|
|
return &ret, nil |
|
|
|
} |
|
|
|
|
|
|
|
func LookupFileId(server string, fileId string) (fullUrl string, err error) { |
|
|
|
func LookupFileId(server string, fileId string, readonly bool) (fullUrl string, err error) { |
|
|
|
parts := strings.Split(fileId, ",") |
|
|
|
if len(parts) != 2 { |
|
|
|
return "", errors.New("Invalid fileId " + fileId) |
|
|
|
@ -72,7 +84,13 @@ func LookupFileId(server string, fileId string) (fullUrl string, err error) { |
|
|
|
if len(lookup.Locations) == 0 { |
|
|
|
return "", errors.New("File Not Found") |
|
|
|
} |
|
|
|
return "http://" + lookup.Locations[rand.Intn(len(lookup.Locations))].Url + "/" + fileId, nil |
|
|
|
var u string |
|
|
|
if readonly{ |
|
|
|
u = lookup.Locations.PickForRead().Url |
|
|
|
}else{ |
|
|
|
u = lookup.Locations.Head().Url |
|
|
|
} |
|
|
|
return "http://" + u + "/" + fileId, nil |
|
|
|
} |
|
|
|
|
|
|
|
// LookupVolumeIds find volume locations by cache and actual lookup
|
|
|
|
|