use grpc to replace http APIs for batch volume id lookup and batch delete

1. remove batch volume id lookup http API /vol/lookup
2. remove batch delete http API /delete
This commit is contained in:
Chris Lu 2018-10-14 00:12:28 -07:00
parent 3ddcd87098
commit ff66269b62
16 changed files with 423 additions and 237 deletions

View File

@ -176,7 +176,7 @@ func (f *Filer) DeleteEntryMetaAndData(p FullPath, isRecursive bool, shouldDelet
}
if shouldDeleteChunks {
f.deleteChunks(entry.Chunks)
f.DeleteChunks(entry.Chunks)
}
if p == "/" {
@ -229,18 +229,18 @@ func (f *Filer) cacheSetDirectory(dirpath string, dirEntry *Entry, level int) {
f.directoryCache.Set(dirpath, dirEntry, time.Duration(minutes)*time.Minute)
}
func (f *Filer) deleteChunks(chunks []*filer_pb.FileChunk) {
func (f *Filer) DeleteChunks(chunks []*filer_pb.FileChunk) {
for _, chunk := range chunks {
f.DeleteFileByFileId(chunk.FileId)
}
}
func (f *Filer) DeleteFileByFileId(fileId string) {
fileUrlOnVolume, err := f.MasterClient.LookupFileId(fileId)
volumeServer, err := f.MasterClient.LookupVolumeServer(fileId)
if err != nil {
glog.V(0).Infof("can not find file %s: %v", fileId, err)
}
if err := operation.DeleteFromVolumeServer(fileUrlOnVolume, ""); err != nil {
if _, err := operation.DeleteFilesAtOneVolumeServer(volumeServer, []string{fileId}); err != nil {
glog.V(0).Infof("deleting file %s: %v", fileId, err)
}
}
@ -251,7 +251,7 @@ func (f *Filer) deleteChunksIfNotNew(oldEntry, newEntry *Entry) {
return
}
if newEntry == nil {
f.deleteChunks(oldEntry.Chunks)
f.DeleteChunks(oldEntry.Chunks)
}
var toDelete []*filer_pb.FileChunk
@ -268,5 +268,5 @@ func (f *Filer) deleteChunksIfNotNew(oldEntry, newEntry *Entry) {
toDelete = append(toDelete, oldChunk)
}
}
f.deleteChunks(toDelete)
f.DeleteChunks(toDelete)
}

View File

@ -10,8 +10,8 @@ import (
"sync"
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/util"
"github.com/chrislusf/seaweedfs/weed/glog"
)
var (
@ -70,16 +70,22 @@ func (cm *ChunkManifest) Marshal() ([]byte, error) {
}
func (cm *ChunkManifest) DeleteChunks(master string) error {
deleteError := 0
var fileIds []string
for _, ci := range cm.Chunks {
if e := DeleteFile(master, ci.Fid, ""); e != nil {
deleteError++
glog.V(0).Infof("Delete %s error: %v, master: %s", ci.Fid, e, master)
fileIds = append(fileIds, ci.Fid)
}
results, err := DeleteFiles(master, fileIds)
if err != nil {
glog.V(0).Infof("delete %+v: %v", fileIds, err)
return fmt.Errorf("chunk delete: %v", err)
}
for _, result := range results {
if result.Error != "" {
glog.V(0).Infof("delete file %+v: %v", result.FileId, result.Error)
return fmt.Errorf("chunk delete %v: %v", result.FileId, result.Error)
}
}
if deleteError > 0 {
return errors.New("Not all chunks deleted.")
}
return nil
}

View File

@ -1,18 +1,15 @@
package operation
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
"sync"
"net/http"
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/util"
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
"context"
"fmt"
)
type DeleteResult struct {
@ -22,27 +19,6 @@ type DeleteResult struct {
Error string `json:"error,omitempty"`
}
func DeleteFromVolumeServer(fileUrlOnVolume string, jwt security.EncodedJwt) error {
err := util.Delete(fileUrlOnVolume, jwt)
if err != nil {
return fmt.Errorf("Failed to delete %s:%v", fileUrlOnVolume, err)
}
return nil
}
func DeleteFile(master string, fileId string, jwt security.EncodedJwt) error {
fileUrl, err := LookupFileId(master, fileId)
if err != nil {
glog.V(0).Infof("Delete %s lookup: %v, master: %s", fileId, err, master)
return nil
}
err = util.Delete(fileUrl, jwt)
if err != nil {
return fmt.Errorf("Failed to delete %s:%v", fileUrl, err)
}
return nil
}
func ParseFileId(fid string) (vid string, key_cookie string, err error) {
commaIndex := strings.Index(fid, ",")
if commaIndex <= 0 {
@ -51,20 +27,18 @@ func ParseFileId(fid string) (vid string, key_cookie string, err error) {
return fid[:commaIndex], fid[commaIndex+1:], nil
}
type DeleteFilesResult struct {
Errors []string
Results []DeleteResult
}
// DeleteFiles batch deletes a list of fileIds
func DeleteFiles(master string, fileIds []string) ([]*volume_server_pb.DeleteResult, error) {
var ret []*volume_server_pb.DeleteResult
func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
vid_to_fileIds := make(map[string][]string)
ret := &DeleteFilesResult{}
var vids []string
for _, fileId := range fileIds {
vid, _, err := ParseFileId(fileId)
if err != nil {
ret.Results = append(ret.Results, DeleteResult{
Fid: vid,
ret = append(ret, &volume_server_pb.DeleteResult{
FileId: vid,
Status: http.StatusBadRequest,
Error: err.Error()},
)
@ -85,7 +59,11 @@ func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
server_to_fileIds := make(map[string][]string)
for vid, result := range lookupResults {
if result.Error != "" {
ret.Errors = append(ret.Errors, result.Error)
ret = append(ret, &volume_server_pb.DeleteResult{
FileId: vid,
Status: http.StatusBadRequest,
Error: err.Error()},
)
continue
}
for _, location := range result.Locations {
@ -103,25 +81,52 @@ func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
wg.Add(1)
go func(server string, fidList []string) {
defer wg.Done()
values := make(url.Values)
for _, fid := range fidList {
values.Add("fid", fid)
if deleteResults, deleteErr := DeleteFilesAtOneVolumeServer(server, fidList); deleteErr != nil {
err = deleteErr
} else {
ret = append(ret, deleteResults...)
}
jsonBlob, err := util.Post("http://"+server+"/delete", values)
if err != nil {
ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
return
}
var result []DeleteResult
err = json.Unmarshal(jsonBlob, &result)
if err != nil {
ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
return
}
ret.Results = append(ret.Results, result...)
}(server, fidList)
}
wg.Wait()
return ret, nil
return ret, err
}
// DeleteFilesAtOneVolumeServer deletes a list of files that is on one volume server via gRpc
func DeleteFilesAtOneVolumeServer(volumeServer string, fileIds []string) (ret []*volume_server_pb.DeleteResult, err error) {
err = withVolumeServerClient(volumeServer, func(volumeServerClient volume_server_pb.VolumeServerClient) error {
req := &volume_server_pb.BatchDeleteRequest{
FileIds: fileIds,
}
resp, err := volumeServerClient.BatchDelete(context.Background(), req)
fmt.Printf("deleted %v %v: %v\n", fileIds, err, resp)
if err != nil {
return err
}
ret = append(ret, resp.Results...)
return nil
})
if err != nil {
return
}
for _, result := range ret {
if result.Error != "" {
return nil, fmt.Errorf("delete fileId %s: %v", result.FileId, result.Error)
}
}
return
}

View File

@ -0,0 +1,53 @@
package operation
import (
"fmt"
"strings"
"strconv"
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
"github.com/chrislusf/seaweedfs/weed/util"
)
func withVolumeServerClient(volumeServer string, fn func(volume_server_pb.VolumeServerClient) error) error {
grpcAddress, err := toVolumeServerGrpcAddress(volumeServer)
if err != nil {
return err
}
grpcConnection, err := util.GrpcDial(grpcAddress)
if err != nil {
return fmt.Errorf("fail to dial %s: %v", grpcAddress, err)
}
defer grpcConnection.Close()
client := volume_server_pb.NewVolumeServerClient(grpcConnection)
return fn(client)
}
func toVolumeServerGrpcAddress(volumeServer string) (grpcAddress string, err error) {
sepIndex := strings.LastIndex(volumeServer, ":")
port, err := strconv.Atoi(volumeServer[sepIndex+1:])
if err != nil {
glog.Errorf("failed to parse volume server address: %v", volumeServer)
return "", err
}
return fmt.Sprintf("%s:%d", volumeServer[0:sepIndex], port+10000), nil
}
func withMasterServerClient(masterServer string, fn func(masterClient master_pb.SeaweedClient) error) error {
grpcConnection, err := util.GrpcDial(masterServer)
if err != nil {
return fmt.Errorf("fail to dial %s: %v", masterServer, err)
}
defer grpcConnection.Close()
client := master_pb.NewSeaweedClient(grpcConnection)
return fn(client)
}

View File

@ -10,6 +10,8 @@ import (
"time"
"github.com/chrislusf/seaweedfs/weed/util"
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
"context"
)
type Location struct {
@ -95,24 +97,41 @@ func LookupVolumeIds(server string, vids []string) (map[string]LookupResult, err
}
//only query unknown_vids
values := make(url.Values)
for _, vid := range unknown_vids {
values.Add("volumeId", vid)
}
jsonBlob, err := util.Post("http://"+server+"/vol/lookup", values)
err := withMasterServerClient(server, func(masterClient master_pb.SeaweedClient) error {
req := &master_pb.LookupVolumeRequest{
VolumeIds: unknown_vids,
}
resp, grpcErr := masterClient.LookupVolume(context.Background(), req)
if grpcErr != nil {
return grpcErr
}
//set newly checked vids to cache
for _, vidLocations := range resp.VolumeIdLocations {
var locations []Location
for _, loc := range vidLocations.Locations {
locations = append(locations, Location{
Url: loc.Url,
PublicUrl: loc.PublicUrl,
})
}
if vidLocations.Error != "" {
vc.Set(vidLocations.VolumeId, locations, 10*time.Minute)
}
ret[vidLocations.VolumeId] = LookupResult{
VolumeId: vidLocations.VolumeId,
Locations: locations,
Error: vidLocations.Error,
}
}
return nil
})
if err != nil {
return nil, err
}
err = json.Unmarshal(jsonBlob, &ret)
if err != nil {
return nil, errors.New(err.Error() + " " + string(jsonBlob))
}
//set newly checked vids to cache
for _, vid := range unknown_vids {
locations := ret[vid].Locations
vc.Set(vid, locations, 10*time.Minute)
}
return ret, nil
}

View File

@ -9,6 +9,8 @@ service Seaweed {
}
rpc KeepConnected (stream ClientListenRequest) returns (stream VolumeLocation) {
}
rpc LookupVolume (LookupVolumeRequest) returns (LookupVolumeResponse) {
}
}
//////////////////////////////////////////////////
@ -69,3 +71,21 @@ message VolumeLocation {
repeated uint32 new_vids = 3;
repeated uint32 deleted_vids = 4;
}
message LookupVolumeRequest {
repeated string volume_ids = 1;
string collection = 2; // optional, a bit faster if provided.
}
message LookupVolumeResponse {
message VolumeIdLocation {
string volume_id = 1;
repeated Location locations = 2;
string error = 3;
}
repeated VolumeIdLocation volume_id_locations = 1;
}
message Location {
string url = 1;
string public_url = 2;
}

View File

@ -16,6 +16,9 @@ It has these top-level messages:
SuperBlockExtra
ClientListenRequest
VolumeLocation
LookupVolumeRequest
LookupVolumeResponse
Location
*/
package master_pb
@ -370,6 +373,104 @@ func (m *VolumeLocation) GetDeletedVids() []uint32 {
return nil
}
type LookupVolumeRequest struct {
VolumeIds []string `protobuf:"bytes,1,rep,name=volume_ids,json=volumeIds" json:"volume_ids,omitempty"`
Collection string `protobuf:"bytes,2,opt,name=collection" json:"collection,omitempty"`
}
func (m *LookupVolumeRequest) Reset() { *m = LookupVolumeRequest{} }
func (m *LookupVolumeRequest) String() string { return proto.CompactTextString(m) }
func (*LookupVolumeRequest) ProtoMessage() {}
func (*LookupVolumeRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *LookupVolumeRequest) GetVolumeIds() []string {
if m != nil {
return m.VolumeIds
}
return nil
}
func (m *LookupVolumeRequest) GetCollection() string {
if m != nil {
return m.Collection
}
return ""
}
type LookupVolumeResponse struct {
VolumeIdLocations []*LookupVolumeResponse_VolumeIdLocation `protobuf:"bytes,1,rep,name=volume_id_locations,json=volumeIdLocations" json:"volume_id_locations,omitempty"`
}
func (m *LookupVolumeResponse) Reset() { *m = LookupVolumeResponse{} }
func (m *LookupVolumeResponse) String() string { return proto.CompactTextString(m) }
func (*LookupVolumeResponse) ProtoMessage() {}
func (*LookupVolumeResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *LookupVolumeResponse) GetVolumeIdLocations() []*LookupVolumeResponse_VolumeIdLocation {
if m != nil {
return m.VolumeIdLocations
}
return nil
}
type LookupVolumeResponse_VolumeIdLocation struct {
VolumeId string `protobuf:"bytes,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"`
Locations []*Location `protobuf:"bytes,2,rep,name=locations" json:"locations,omitempty"`
Error string `protobuf:"bytes,3,opt,name=error" json:"error,omitempty"`
}
func (m *LookupVolumeResponse_VolumeIdLocation) Reset() { *m = LookupVolumeResponse_VolumeIdLocation{} }
func (m *LookupVolumeResponse_VolumeIdLocation) String() string { return proto.CompactTextString(m) }
func (*LookupVolumeResponse_VolumeIdLocation) ProtoMessage() {}
func (*LookupVolumeResponse_VolumeIdLocation) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{8, 0}
}
func (m *LookupVolumeResponse_VolumeIdLocation) GetVolumeId() string {
if m != nil {
return m.VolumeId
}
return ""
}
func (m *LookupVolumeResponse_VolumeIdLocation) GetLocations() []*Location {
if m != nil {
return m.Locations
}
return nil
}
func (m *LookupVolumeResponse_VolumeIdLocation) GetError() string {
if m != nil {
return m.Error
}
return ""
}
type Location struct {
Url string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"`
PublicUrl string `protobuf:"bytes,2,opt,name=public_url,json=publicUrl" json:"public_url,omitempty"`
}
func (m *Location) Reset() { *m = Location{} }
func (m *Location) String() string { return proto.CompactTextString(m) }
func (*Location) ProtoMessage() {}
func (*Location) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (m *Location) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
func (m *Location) GetPublicUrl() string {
if m != nil {
return m.PublicUrl
}
return ""
}
func init() {
proto.RegisterType((*Heartbeat)(nil), "master_pb.Heartbeat")
proto.RegisterType((*HeartbeatResponse)(nil), "master_pb.HeartbeatResponse")
@ -379,6 +480,10 @@ func init() {
proto.RegisterType((*SuperBlockExtra_ErasureCoding)(nil), "master_pb.SuperBlockExtra.ErasureCoding")
proto.RegisterType((*ClientListenRequest)(nil), "master_pb.ClientListenRequest")
proto.RegisterType((*VolumeLocation)(nil), "master_pb.VolumeLocation")
proto.RegisterType((*LookupVolumeRequest)(nil), "master_pb.LookupVolumeRequest")
proto.RegisterType((*LookupVolumeResponse)(nil), "master_pb.LookupVolumeResponse")
proto.RegisterType((*LookupVolumeResponse_VolumeIdLocation)(nil), "master_pb.LookupVolumeResponse.VolumeIdLocation")
proto.RegisterType((*Location)(nil), "master_pb.Location")
}
// Reference imports to suppress errors if they are not otherwise used.
@ -394,6 +499,7 @@ const _ = grpc.SupportPackageIsVersion4
type SeaweedClient interface {
SendHeartbeat(ctx context.Context, opts ...grpc.CallOption) (Seaweed_SendHeartbeatClient, error)
KeepConnected(ctx context.Context, opts ...grpc.CallOption) (Seaweed_KeepConnectedClient, error)
LookupVolume(ctx context.Context, in *LookupVolumeRequest, opts ...grpc.CallOption) (*LookupVolumeResponse, error)
}
type seaweedClient struct {
@ -466,11 +572,21 @@ func (x *seaweedKeepConnectedClient) Recv() (*VolumeLocation, error) {
return m, nil
}
func (c *seaweedClient) LookupVolume(ctx context.Context, in *LookupVolumeRequest, opts ...grpc.CallOption) (*LookupVolumeResponse, error) {
out := new(LookupVolumeResponse)
err := grpc.Invoke(ctx, "/master_pb.Seaweed/LookupVolume", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Seaweed service
type SeaweedServer interface {
SendHeartbeat(Seaweed_SendHeartbeatServer) error
KeepConnected(Seaweed_KeepConnectedServer) error
LookupVolume(context.Context, *LookupVolumeRequest) (*LookupVolumeResponse, error)
}
func RegisterSeaweedServer(s *grpc.Server, srv SeaweedServer) {
@ -529,10 +645,33 @@ func (x *seaweedKeepConnectedServer) Recv() (*ClientListenRequest, error) {
return m, nil
}
func _Seaweed_LookupVolume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LookupVolumeRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedServer).LookupVolume(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/master_pb.Seaweed/LookupVolume",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedServer).LookupVolume(ctx, req.(*LookupVolumeRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Seaweed_serviceDesc = grpc.ServiceDesc{
ServiceName: "master_pb.Seaweed",
HandlerType: (*SeaweedServer)(nil),
Methods: []grpc.MethodDesc{},
Methods: []grpc.MethodDesc{
{
MethodName: "LookupVolume",
Handler: _Seaweed_LookupVolume_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "SendHeartbeat",
@ -553,51 +692,59 @@ var _Seaweed_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("master.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 724 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x54, 0xc1, 0x6e, 0xd3, 0x4c,
0x10, 0xfe, 0x9d, 0xa4, 0x49, 0x3c, 0x69, 0xd2, 0x74, 0xff, 0x5f, 0xbf, 0xdc, 0x52, 0x4a, 0x30,
0x17, 0x23, 0x50, 0x84, 0xca, 0x99, 0x4b, 0xa3, 0x22, 0xaa, 0x16, 0xb5, 0x72, 0x44, 0x0f, 0x5c,
0xac, 0x8d, 0x3d, 0xad, 0x56, 0x5d, 0xaf, 0xcd, 0xee, 0xa6, 0x8d, 0x7b, 0xe1, 0x6d, 0x78, 0x0c,
0x4e, 0xbc, 0x0d, 0x2f, 0x81, 0x76, 0x6d, 0xa7, 0x21, 0x2d, 0xdc, 0x66, 0xbf, 0x99, 0xd9, 0x9d,
0xfd, 0xbe, 0x99, 0x81, 0xcd, 0x94, 0x2a, 0x8d, 0x72, 0x9c, 0xcb, 0x4c, 0x67, 0xc4, 0x2d, 0x4f,
0x51, 0x3e, 0xf3, 0x7f, 0x36, 0xc0, 0xfd, 0x80, 0x54, 0xea, 0x19, 0x52, 0x4d, 0x06, 0xd0, 0x60,
0xb9, 0xe7, 0x8c, 0x9c, 0xc0, 0x0d, 0x1b, 0x2c, 0x27, 0x04, 0x5a, 0x79, 0x26, 0xb5, 0xd7, 0x18,
0x39, 0x41, 0x3f, 0xb4, 0x36, 0x79, 0x0a, 0x90, 0xcf, 0x67, 0x9c, 0xc5, 0xd1, 0x5c, 0x72, 0xaf,
0x69, 0x63, 0xdd, 0x12, 0xf9, 0x24, 0x39, 0x09, 0x60, 0x98, 0xd2, 0x45, 0x74, 0x93, 0xf1, 0x79,
0x8a, 0x51, 0x9c, 0xcd, 0x85, 0xf6, 0x5a, 0x36, 0x7d, 0x90, 0xd2, 0xc5, 0x85, 0x85, 0x27, 0x06,
0x25, 0x23, 0x53, 0xd5, 0x22, 0xba, 0x64, 0x1c, 0xa3, 0x6b, 0x2c, 0xbc, 0x8d, 0x91, 0x13, 0xb4,
0x42, 0x48, 0xe9, 0xe2, 0x3d, 0xe3, 0x78, 0x82, 0x05, 0x79, 0x06, 0xbd, 0x84, 0x6a, 0x1a, 0xc5,
0x28, 0x34, 0x4a, 0xaf, 0x6d, 0xdf, 0x02, 0x03, 0x4d, 0x2c, 0x62, 0xea, 0x93, 0x34, 0xbe, 0xf6,
0x3a, 0xd6, 0x63, 0x6d, 0x53, 0x1f, 0x4d, 0x52, 0x26, 0x22, 0x5b, 0x79, 0xd7, 0x3e, 0xed, 0x5a,
0xe4, 0xdc, 0x94, 0xff, 0x0e, 0x3a, 0x65, 0x6d, 0xca, 0x73, 0x47, 0xcd, 0xa0, 0x77, 0xf0, 0x62,
0xbc, 0x64, 0x63, 0x5c, 0x96, 0x77, 0x2c, 0x2e, 0x33, 0x99, 0x52, 0xcd, 0x32, 0xf1, 0x11, 0x95,
0xa2, 0x57, 0x18, 0xd6, 0x39, 0x64, 0x07, 0xba, 0x02, 0x6f, 0xa3, 0x1b, 0x96, 0x28, 0x0f, 0x46,
0xcd, 0xa0, 0x1f, 0x76, 0x04, 0xde, 0x5e, 0xb0, 0x44, 0x91, 0xe7, 0xb0, 0x99, 0x20, 0x47, 0x8d,
0x49, 0xe9, 0xee, 0x59, 0x77, 0xaf, 0xc2, 0x4c, 0x88, 0xaf, 0x60, 0x7b, 0x49, 0x76, 0x88, 0x2a,
0xcf, 0x84, 0x42, 0x12, 0xc0, 0x56, 0x79, 0xfb, 0x94, 0xdd, 0xe1, 0x29, 0x4b, 0x99, 0xb6, 0x0a,
0xb4, 0xc2, 0x75, 0x98, 0xec, 0x81, 0xab, 0x30, 0x96, 0xa8, 0x4f, 0xb0, 0xb0, 0x9a, 0xb8, 0xe1,
0x3d, 0x40, 0xfe, 0x87, 0x36, 0x47, 0x9a, 0xa0, 0xac, 0x44, 0xa9, 0x4e, 0xfe, 0x8f, 0x06, 0x78,
0x7f, 0xfa, 0x98, 0x55, 0x3c, 0xb1, 0xef, 0xf5, 0xc3, 0x06, 0x4b, 0x0c, 0xa3, 0x8a, 0xdd, 0xa1,
0xbd, 0xbd, 0x15, 0x5a, 0x9b, 0xec, 0x03, 0xc4, 0x19, 0xe7, 0x18, 0x9b, 0xc4, 0xea, 0xf2, 0x15,
0xc4, 0x30, 0x6e, 0x45, 0xbc, 0x17, 0xbb, 0x15, 0xba, 0x06, 0x29, 0x75, 0x5e, 0xf2, 0x52, 0x05,
0x94, 0x3a, 0x57, 0xbc, 0x94, 0x21, 0xaf, 0x81, 0xd4, 0xd4, 0xcd, 0x8a, 0x65, 0x60, 0xdb, 0x06,
0x0e, 0x2b, 0xcf, 0x61, 0x51, 0x47, 0x3f, 0x01, 0x57, 0x22, 0x4d, 0xa2, 0x4c, 0xf0, 0xc2, 0x4a,
0xdf, 0x0d, 0xbb, 0x06, 0x38, 0x13, 0xbc, 0x20, 0xaf, 0x60, 0x5b, 0x62, 0xce, 0x59, 0x4c, 0xa3,
0x9c, 0xd3, 0x18, 0x53, 0x14, 0x75, 0x17, 0x0c, 0x2b, 0xc7, 0x79, 0x8d, 0x13, 0x0f, 0x3a, 0x37,
0x28, 0x95, 0xf9, 0x96, 0x6b, 0x43, 0xea, 0x23, 0x19, 0x42, 0x53, 0x6b, 0xee, 0x81, 0x45, 0x8d,
0xe9, 0x77, 0x60, 0xe3, 0x28, 0xcd, 0x75, 0xe1, 0x7f, 0x77, 0x60, 0x6b, 0x3a, 0xcf, 0x51, 0x1e,
0xf2, 0x2c, 0xbe, 0x3e, 0x5a, 0x68, 0x49, 0xc9, 0x19, 0x0c, 0x50, 0x52, 0x35, 0x97, 0xa6, 0xf6,
0x84, 0x89, 0x2b, 0x4b, 0x69, 0xef, 0x20, 0x58, 0x69, 0xae, 0xb5, 0x9c, 0xf1, 0x51, 0x99, 0x30,
0xb1, 0xf1, 0x61, 0x1f, 0x57, 0x8f, 0xbb, 0x9f, 0xa1, 0xff, 0x9b, 0xdf, 0x08, 0x63, 0x1a, 0xbf,
0x92, 0xca, 0xda, 0x46, 0xf1, 0x9c, 0x4a, 0xa6, 0x8b, 0x6a, 0x40, 0xab, 0x93, 0x11, 0xa4, 0x9a,
0x3f, 0xd3, 0x87, 0x4d, 0xdb, 0x87, 0x6e, 0x89, 0x1c, 0x27, 0xca, 0x7f, 0x09, 0xff, 0x4e, 0x38,
0x43, 0xa1, 0x4f, 0x99, 0xd2, 0x28, 0x42, 0xfc, 0x32, 0x47, 0xa5, 0xcd, 0x0b, 0x82, 0xa6, 0x58,
0x8d, 0xbf, 0xb5, 0xfd, 0xaf, 0x30, 0x28, 0x5b, 0xe7, 0x34, 0x8b, 0x6d, 0xdf, 0x18, 0x62, 0xcc,
0xdc, 0x97, 0x41, 0xc6, 0x5c, 0x5b, 0x08, 0x8d, 0xf5, 0x85, 0xb0, 0x3a, 0x31, 0xcd, 0xbf, 0x4f,
0x4c, 0xeb, 0xc1, 0xc4, 0x1c, 0x7c, 0x73, 0xa0, 0x33, 0x45, 0x7a, 0x8b, 0x98, 0x90, 0x63, 0xe8,
0x4f, 0x51, 0x24, 0xf7, 0xeb, 0xea, 0xbf, 0x15, 0x76, 0x97, 0xe8, 0xee, 0xde, 0x63, 0x68, 0x3d,
0x6d, 0xfe, 0x3f, 0x81, 0xf3, 0xc6, 0x21, 0xe7, 0xd0, 0x3f, 0x41, 0xcc, 0x27, 0x99, 0x10, 0x18,
0x6b, 0x4c, 0xc8, 0xfe, 0x4a, 0xd2, 0x23, 0xe4, 0xec, 0xee, 0x3c, 0xd8, 0x12, 0x35, 0x23, 0xe5,
0x8d, 0xb3, 0xb6, 0x5d, 0xad, 0x6f, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x19, 0xb5, 0xf3, 0x01,
0x6a, 0x05, 0x00, 0x00,
// 855 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xcf, 0x6f, 0xdc, 0x44,
0x14, 0xae, 0xbd, 0x9b, 0xec, 0xfa, 0x6d, 0x36, 0xdd, 0x4c, 0x22, 0xe4, 0x2e, 0xa5, 0x5d, 0xcc,
0xc5, 0x08, 0x14, 0x95, 0x70, 0x44, 0x5c, 0xba, 0x0a, 0x22, 0x4a, 0x50, 0x83, 0x03, 0x3d, 0x70,
0x31, 0xb3, 0xf6, 0x6b, 0x35, 0xca, 0x78, 0x6c, 0x66, 0x66, 0x93, 0x75, 0x2f, 0xfc, 0x67, 0x9c,
0xf8, 0x6f, 0xb8, 0x71, 0xe3, 0x86, 0x66, 0x3c, 0xde, 0x1f, 0x6e, 0x00, 0x89, 0xdb, 0x9b, 0x6f,
0xde, 0x8f, 0x6f, 0xde, 0xf7, 0x9e, 0x0d, 0x07, 0x05, 0x55, 0x1a, 0xe5, 0x69, 0x25, 0x4b, 0x5d,
0x92, 0xa0, 0x39, 0xa5, 0xd5, 0x22, 0xfa, 0xc3, 0x87, 0xe0, 0x5b, 0xa4, 0x52, 0x2f, 0x90, 0x6a,
0x72, 0x08, 0x3e, 0xab, 0x42, 0x6f, 0xe6, 0xc5, 0x41, 0xe2, 0xb3, 0x8a, 0x10, 0xe8, 0x57, 0xa5,
0xd4, 0xa1, 0x3f, 0xf3, 0xe2, 0x71, 0x62, 0x6d, 0xf2, 0x11, 0x40, 0xb5, 0x5c, 0x70, 0x96, 0xa5,
0x4b, 0xc9, 0xc3, 0x9e, 0xf5, 0x0d, 0x1a, 0xe4, 0x47, 0xc9, 0x49, 0x0c, 0x93, 0x82, 0xae, 0xd2,
0xbb, 0x92, 0x2f, 0x0b, 0x4c, 0xb3, 0x72, 0x29, 0x74, 0xd8, 0xb7, 0xe1, 0x87, 0x05, 0x5d, 0xbd,
0xb6, 0xf0, 0xdc, 0xa0, 0x64, 0x66, 0x58, 0xad, 0xd2, 0x37, 0x8c, 0x63, 0x7a, 0x8b, 0x75, 0xb8,
0x37, 0xf3, 0xe2, 0x7e, 0x02, 0x05, 0x5d, 0x7d, 0xc3, 0x38, 0x5e, 0x62, 0x4d, 0x9e, 0xc3, 0x28,
0xa7, 0x9a, 0xa6, 0x19, 0x0a, 0x8d, 0x32, 0xdc, 0xb7, 0xb5, 0xc0, 0x40, 0x73, 0x8b, 0x18, 0x7e,
0x92, 0x66, 0xb7, 0xe1, 0xc0, 0xde, 0x58, 0xdb, 0xf0, 0xa3, 0x79, 0xc1, 0x44, 0x6a, 0x99, 0x0f,
0x6d, 0xe9, 0xc0, 0x22, 0xd7, 0x86, 0xfe, 0xd7, 0x30, 0x68, 0xb8, 0xa9, 0x30, 0x98, 0xf5, 0xe2,
0xd1, 0xd9, 0x27, 0xa7, 0xeb, 0x6e, 0x9c, 0x36, 0xf4, 0x2e, 0xc4, 0x9b, 0x52, 0x16, 0x54, 0xb3,
0x52, 0x7c, 0x87, 0x4a, 0xd1, 0xb7, 0x98, 0xb4, 0x31, 0xe4, 0x09, 0x0c, 0x05, 0xde, 0xa7, 0x77,
0x2c, 0x57, 0x21, 0xcc, 0x7a, 0xf1, 0x38, 0x19, 0x08, 0xbc, 0x7f, 0xcd, 0x72, 0x45, 0x3e, 0x86,
0x83, 0x1c, 0x39, 0x6a, 0xcc, 0x9b, 0xeb, 0x91, 0xbd, 0x1e, 0x39, 0xcc, 0xb8, 0x44, 0x0a, 0x8e,
0xd6, 0xcd, 0x4e, 0x50, 0x55, 0xa5, 0x50, 0x48, 0x62, 0x78, 0xdc, 0x64, 0xbf, 0x61, 0xef, 0xf0,
0x8a, 0x15, 0x4c, 0x5b, 0x05, 0xfa, 0x49, 0x17, 0x26, 0x4f, 0x21, 0x50, 0x98, 0x49, 0xd4, 0x97,
0x58, 0x5b, 0x4d, 0x82, 0x64, 0x03, 0x90, 0x0f, 0x60, 0x9f, 0x23, 0xcd, 0x51, 0x3a, 0x51, 0xdc,
0x29, 0xfa, 0xdd, 0x87, 0xf0, 0x9f, 0x1e, 0x66, 0x15, 0xcf, 0x6d, 0xbd, 0x71, 0xe2, 0xb3, 0xdc,
0x74, 0x54, 0xb1, 0x77, 0x68, 0xb3, 0xf7, 0x13, 0x6b, 0x93, 0x67, 0x00, 0x59, 0xc9, 0x39, 0x66,
0x26, 0xd0, 0x25, 0xdf, 0x42, 0x4c, 0xc7, 0xad, 0x88, 0x1b, 0xb1, 0xfb, 0x49, 0x60, 0x90, 0x46,
0xe7, 0x75, 0x5f, 0x9c, 0x43, 0xa3, 0xb3, 0xeb, 0x4b, 0xe3, 0xf2, 0x39, 0x90, 0xb6, 0x75, 0x8b,
0x7a, 0xed, 0xb8, 0x6f, 0x1d, 0x27, 0xee, 0xe6, 0x65, 0xdd, 0x7a, 0x7f, 0x08, 0x81, 0x44, 0x9a,
0xa7, 0xa5, 0xe0, 0xb5, 0x95, 0x7e, 0x98, 0x0c, 0x0d, 0xf0, 0x4a, 0xf0, 0x9a, 0x7c, 0x06, 0x47,
0x12, 0x2b, 0xce, 0x32, 0x9a, 0x56, 0x9c, 0x66, 0x58, 0xa0, 0x68, 0xa7, 0x60, 0xe2, 0x2e, 0xae,
0x5b, 0x9c, 0x84, 0x30, 0xb8, 0x43, 0xa9, 0xcc, 0xb3, 0x02, 0xeb, 0xd2, 0x1e, 0xc9, 0x04, 0x7a,
0x5a, 0xf3, 0x10, 0x2c, 0x6a, 0xcc, 0x68, 0x00, 0x7b, 0xe7, 0x45, 0xa5, 0xeb, 0xe8, 0x37, 0x0f,
0x1e, 0xdf, 0x2c, 0x2b, 0x94, 0x2f, 0x79, 0x99, 0xdd, 0x9e, 0xaf, 0xb4, 0xa4, 0xe4, 0x15, 0x1c,
0xa2, 0xa4, 0x6a, 0x29, 0x0d, 0xf7, 0x9c, 0x89, 0xb7, 0xb6, 0xa5, 0xa3, 0xb3, 0x78, 0x6b, 0xb8,
0x3a, 0x31, 0xa7, 0xe7, 0x4d, 0xc0, 0xdc, 0xfa, 0x27, 0x63, 0xdc, 0x3e, 0x4e, 0x7f, 0x82, 0xf1,
0xce, 0xbd, 0x11, 0xc6, 0x0c, 0xbe, 0x93, 0xca, 0xda, 0x46, 0xf1, 0x8a, 0x4a, 0xa6, 0x6b, 0xb7,
0xa0, 0xee, 0x64, 0x04, 0x71, 0xfb, 0x67, 0xe6, 0xb0, 0x67, 0xe7, 0x30, 0x68, 0x90, 0x8b, 0x5c,
0x45, 0x9f, 0xc2, 0xf1, 0x9c, 0x33, 0x14, 0xfa, 0x8a, 0x29, 0x8d, 0x22, 0xc1, 0x5f, 0x96, 0xa8,
0xb4, 0xa9, 0x20, 0x68, 0x81, 0x6e, 0xfd, 0xad, 0x1d, 0xfd, 0x0a, 0x87, 0xcd, 0xe8, 0x5c, 0x95,
0x99, 0x9d, 0x1b, 0xd3, 0x18, 0xb3, 0xf7, 0x8d, 0x93, 0x31, 0x3b, 0x1f, 0x04, 0xbf, 0xfb, 0x41,
0xd8, 0xde, 0x98, 0xde, 0xbf, 0x6f, 0x4c, 0xff, 0xfd, 0x8d, 0xf9, 0x01, 0x8e, 0xaf, 0xca, 0xf2,
0x76, 0x59, 0x35, 0x34, 0x5a, 0xae, 0xbb, 0x2f, 0xf4, 0x66, 0x3d, 0x53, 0x73, 0xfd, 0xc2, 0xce,
0xc4, 0xfa, 0xdd, 0x89, 0x8d, 0xfe, 0xf4, 0xe0, 0x64, 0x37, 0xad, 0xdb, 0xc5, 0x9f, 0xe1, 0x78,
0x9d, 0x37, 0xe5, 0xee, 0xcd, 0x4d, 0x81, 0xd1, 0xd9, 0x8b, 0x2d, 0x31, 0x1f, 0x8a, 0x6e, 0x3f,
0x1f, 0x79, 0xdb, 0xac, 0xe4, 0xe8, 0xae, 0x83, 0xa8, 0xe9, 0x0a, 0x26, 0x5d, 0x37, 0x33, 0xd0,
0xeb, 0xaa, 0xae, 0xb3, 0xc3, 0x36, 0x92, 0x7c, 0x01, 0xc1, 0x86, 0x88, 0x6f, 0x89, 0x1c, 0xef,
0x10, 0x71, 0xb5, 0x36, 0x5e, 0xe4, 0x04, 0xf6, 0x50, 0xca, 0xb2, 0xfd, 0x10, 0x34, 0x87, 0xe8,
0x2b, 0x18, 0xfe, 0x6f, 0x15, 0xcf, 0xfe, 0xf2, 0x60, 0x70, 0x83, 0xf4, 0x1e, 0x31, 0x27, 0x17,
0x30, 0xbe, 0x41, 0x91, 0x6f, 0x7e, 0x1b, 0x27, 0x5b, 0x7c, 0xd6, 0xe8, 0xf4, 0xe9, 0x43, 0x68,
0xdb, 0xab, 0xe8, 0x51, 0xec, 0xbd, 0xf0, 0xc8, 0x35, 0x8c, 0x2f, 0x11, 0xab, 0x79, 0x29, 0x04,
0x66, 0x1a, 0x73, 0xf2, 0x6c, 0x2b, 0xe8, 0x81, 0x21, 0x9d, 0x3e, 0x79, 0xef, 0x6b, 0xdd, 0xbe,
0xc9, 0x65, 0xfc, 0x1e, 0x0e, 0xb6, 0xb5, 0xd9, 0x49, 0xf8, 0xc0, 0x24, 0x4d, 0x9f, 0xff, 0x87,
0xa8, 0xd1, 0xa3, 0xc5, 0xbe, 0xfd, 0x6b, 0x7e, 0xf9, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa1,
0x9f, 0x87, 0x2e, 0x45, 0x07, 0x00, 0x00,
}

View File

@ -132,17 +132,6 @@ func submitForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl st
return
}
func deleteForClientHandler(w http.ResponseWriter, r *http.Request, masterUrl string) {
r.ParseForm()
fids := r.Form["fid"]
ret, err := operation.DeleteFiles(masterUrl, fids)
if err != nil {
writeJsonError(w, r, http.StatusInternalServerError, err)
return
}
writeJsonQuiet(w, r, http.StatusAccepted, ret)
}
func parseURLPath(path string) (vid, fid, filename, ext string, isVolumeIdOnly bool) {
switch strings.Count(path, "/") {
case 3:

View File

@ -110,10 +110,7 @@ func (fs *FilerServer) CreateEntry(ctx context.Context, req *filer_pb.CreateEntr
fullpath := filer2.FullPath(filepath.Join(req.Directory, req.Entry.Name))
chunks, garbages := filer2.CompactFileChunks(req.Entry.Chunks)
for _, garbage := range garbages {
glog.V(0).Infof("deleting %s garbage chunk: %v, [%d, %d)", fullpath, garbage.FileId, garbage.Offset, garbage.Offset+int64(garbage.Size))
fs.filer.DeleteFileByFileId(garbage.FileId)
}
fs.filer.DeleteChunks(garbages)
err = fs.filer.CreateEntry(&filer2.Entry{
FullPath: fullpath,
@ -168,14 +165,8 @@ func (fs *FilerServer) UpdateEntry(ctx context.Context, req *filer_pb.UpdateEntr
}
if err = fs.filer.UpdateEntry(newEntry); err == nil {
for _, garbage := range unusedChunks {
glog.V(0).Infof("deleting %s old chunk: %v, [%d, %d)", fullpath, garbage.FileId, garbage.Offset, garbage.Offset+int64(garbage.Size))
fs.filer.DeleteFileByFileId(garbage.FileId)
}
for _, garbage := range garbages {
glog.V(0).Infof("deleting %s garbage chunk: %v, [%d, %d)", fullpath, garbage.FileId, garbage.Offset, garbage.Offset+int64(garbage.Size))
fs.filer.DeleteFileByFileId(garbage.FileId)
}
fs.filer.DeleteChunks(unusedChunks)
fs.filer.DeleteChunks(garbages)
}
fs.filer.NotifyUpdateEvent(entry, newEntry, true)

View File

@ -0,0 +1,28 @@
package weed_server
import (
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
"context"
)
func (ms *MasterServer) LookupVolume(ctx context.Context, req *master_pb.LookupVolumeRequest) (*master_pb.LookupVolumeResponse, error) {
resp := &master_pb.LookupVolumeResponse{}
volumeLocations := ms.lookupVolumeId(req.VolumeIds, req.Collection)
for _, result := range volumeLocations {
var locations []*master_pb.Location
for _, loc := range result.Locations {
locations = append(locations, &master_pb.Location{
Url: loc.Url,
PublicUrl: loc.PublicUrl,
})
}
resp.VolumeIdLocations = append(resp.VolumeIdLocations, &master_pb.LookupVolumeResponse_VolumeIdLocation{
VolumeId: result.VolumeId,
Locations: locations,
Error: result.Error,
})
}
return resp, nil
}

View File

@ -76,12 +76,10 @@ func NewMasterServer(r *mux.Router, port int, metaFolder string,
r.HandleFunc("/dir/lookup", ms.proxyToLeader(ms.guard.WhiteList(ms.dirLookupHandler)))
r.HandleFunc("/dir/status", ms.proxyToLeader(ms.guard.WhiteList(ms.dirStatusHandler)))
r.HandleFunc("/col/delete", ms.proxyToLeader(ms.guard.WhiteList(ms.collectionDeleteHandler)))
r.HandleFunc("/vol/lookup", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeLookupHandler)))
r.HandleFunc("/vol/grow", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeGrowHandler)))
r.HandleFunc("/vol/status", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeStatusHandler)))
r.HandleFunc("/vol/vacuum", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeVacuumHandler)))
r.HandleFunc("/submit", ms.guard.WhiteList(ms.submitFromMasterServerHandler))
r.HandleFunc("/delete", ms.guard.WhiteList(ms.deleteFromMasterServerHandler))
r.HandleFunc("/stats/health", ms.guard.WhiteList(statsHealthHandler))
r.HandleFunc("/stats/counter", ms.guard.WhiteList(statsCounterHandler))
r.HandleFunc("/stats/memory", ms.guard.WhiteList(statsMemoryHandler))

View File

@ -58,15 +58,6 @@ func (ms *MasterServer) dirLookupHandler(w http.ResponseWriter, r *http.Request)
writeJsonQuiet(w, r, httpStatus, location)
}
// This can take batched volumeIds, &volumeId=x&volumeId=y&volumeId=z
func (ms *MasterServer) volumeLookupHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
vids := r.Form["volumeId"]
collection := r.FormValue("collection") //optional, but can be faster if too many collections
volumeLocations := ms.lookupVolumeId(vids, collection)
writeJsonQuiet(w, r, http.StatusOK, volumeLocations)
}
func (ms *MasterServer) dirAssignHandler(w http.ResponseWriter, r *http.Request) {
stats.AssignRequest()
requestedCount, e := strconv.ParseUint(r.FormValue("count"), 10, 64)

View File

@ -119,14 +119,6 @@ func (ms *MasterServer) submitFromMasterServerHandler(w http.ResponseWriter, r *
}
}
func (ms *MasterServer) deleteFromMasterServerHandler(w http.ResponseWriter, r *http.Request) {
if ms.Topo.IsLeader() {
deleteForClientHandler(w, r, ms.selfUrl(r))
} else {
deleteForClientHandler(w, r, ms.Topo.RaftServer.Leader())
}
}
func (ms *MasterServer) HasWritableVolume(option *topology.VolumeGrowOption) bool {
vl := ms.Topo.GetVolumeLayout(option.Collection, option.ReplicaPlacement, option.Ttl)
return vl.GetActiveVolumeCount(option) > 0

View File

@ -62,7 +62,6 @@ func NewVolumeServer(adminMux, publicMux *http.ServeMux, ip string,
adminMux.HandleFunc("/stats/counter", vs.guard.WhiteList(statsCounterHandler))
adminMux.HandleFunc("/stats/memory", vs.guard.WhiteList(statsMemoryHandler))
adminMux.HandleFunc("/stats/disk", vs.guard.WhiteList(vs.statsDiskHandler))
adminMux.HandleFunc("/delete", vs.guard.WhiteList(vs.batchDeleteHandler))
adminMux.HandleFunc("/", vs.privateStoreHandler)
if publicMux != adminMux {
// separated admin and public port

View File

@ -109,71 +109,6 @@ func (vs *VolumeServer) DeleteHandler(w http.ResponseWriter, r *http.Request) {
}
//Experts only: takes multiple fid parameters. This function does not propagate deletes to replicas.
func (vs *VolumeServer) batchDeleteHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var ret []operation.DeleteResult
now := uint64(time.Now().Unix())
for _, fid := range r.Form["fid"] {
vid, id_cookie, err := operation.ParseFileId(fid)
if err != nil {
ret = append(ret, operation.DeleteResult{
Fid: fid,
Status: http.StatusBadRequest,
Error: err.Error()})
continue
}
n := new(storage.Needle)
volumeId, _ := storage.NewVolumeId(vid)
n.ParsePath(id_cookie)
// glog.V(4).Infoln("batch deleting", n)
cookie := n.Cookie
if _, err := vs.store.ReadVolumeNeedle(volumeId, n); err != nil {
ret = append(ret, operation.DeleteResult{
Fid: fid,
Status: http.StatusNotFound,
Error: err.Error(),
})
continue
}
if n.IsChunkedManifest() {
ret = append(ret, operation.DeleteResult{
Fid: fid,
Status: http.StatusNotAcceptable,
Error: "ChunkManifest: not allowed in batch delete mode.",
})
continue
}
if n.Cookie != cookie {
ret = append(ret, operation.DeleteResult{
Fid: fid,
Status: http.StatusBadRequest,
Error: "File Random Cookie does not match.",
})
glog.V(0).Infoln("deleting", fid, "with unmaching cookie from ", r.RemoteAddr, "agent", r.UserAgent())
return
}
n.LastModified = now
if size, err := vs.store.Delete(volumeId, n); err != nil {
ret = append(ret, operation.DeleteResult{
Fid: fid,
Status: http.StatusInternalServerError,
Error: err.Error()},
)
} else {
ret = append(ret, operation.DeleteResult{
Fid: fid,
Status: http.StatusAccepted,
Size: int(size)},
)
}
}
writeJsonQuiet(w, r, http.StatusAccepted, ret)
}
func setEtag(w http.ResponseWriter, etag string) {
if etag != "" {
if strings.HasPrefix(etag, "\"") {

View File

@ -54,6 +54,19 @@ func (vc *vidMap) LookupFileId(fileId string) (fullUrl string, err error) {
return "http://" + serverUrl + "/" + fileId, nil
}
func (vc *vidMap) LookupVolumeServer(fileId string) (volumeServer string, err error) {
parts := strings.Split(fileId, ",")
if len(parts) != 2 {
return "", errors.New("Invalid fileId " + fileId)
}
serverUrl, lookupError := vc.LookupVolumeServerUrl(parts[0])
if lookupError != nil {
return "", lookupError
}
return serverUrl, nil
}
func (vc *vidMap) GetLocations(vid uint32) (locations []Location) {
vc.RLock()
defer vc.RUnlock()