Chris Lu
6 years ago
6 changed files with 217 additions and 65 deletions
-
4weed/command/download.go
-
2weed/replication/replicator.go
-
122weed/replication/sink/fetch_write.go
-
138weed/replication/sink/filer_sink.go
-
11weed/replication/source/filer_source.go
-
5weed/util/http_util.go
@ -0,0 +1,122 @@ |
|||
package sink |
|||
|
|||
import ( |
|||
"context" |
|||
"sync" |
|||
"strings" |
|||
"fmt" |
|||
"github.com/chrislusf/seaweedfs/weed/glog" |
|||
"github.com/chrislusf/seaweedfs/weed/operation" |
|||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" |
|||
"github.com/chrislusf/seaweedfs/weed/util" |
|||
) |
|||
|
|||
func (fs *FilerSink) replicateChunks(sourceChunks []*filer_pb.FileChunk) (replicatedChunks []*filer_pb.FileChunk, err error) { |
|||
if len(sourceChunks) == 0 { |
|||
return |
|||
} |
|||
var wg sync.WaitGroup |
|||
for _, sourceChunk := range sourceChunks { |
|||
wg.Add(1) |
|||
go func(chunk *filer_pb.FileChunk) { |
|||
defer wg.Done() |
|||
replicatedChunk, e := fs.replicateOneChunk(chunk) |
|||
if e != nil { |
|||
err = e |
|||
} |
|||
replicatedChunks = append(replicatedChunks, replicatedChunk) |
|||
}(sourceChunk) |
|||
} |
|||
wg.Wait() |
|||
|
|||
return |
|||
} |
|||
|
|||
func (fs *FilerSink) replicateOneChunk(sourceChunk *filer_pb.FileChunk) (*filer_pb.FileChunk, error) { |
|||
|
|||
fileId, err := fs.fetchAndWrite(sourceChunk) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("copy %s: %v", sourceChunk.FileId, err) |
|||
} |
|||
|
|||
return &filer_pb.FileChunk{ |
|||
FileId: fileId, |
|||
Offset: sourceChunk.Offset, |
|||
Size: sourceChunk.Size, |
|||
Mtime: sourceChunk.Mtime, |
|||
ETag: sourceChunk.ETag, |
|||
SourceFileId: sourceChunk.FileId, |
|||
}, nil |
|||
} |
|||
|
|||
func (fs *FilerSink) fetchAndWrite(sourceChunk *filer_pb.FileChunk) (fileId string, err error) { |
|||
|
|||
filename, header, readCloser, err := fs.filerSource.ReadPart(sourceChunk.FileId) |
|||
if err != nil { |
|||
return "", fmt.Errorf("read part %s: %v", sourceChunk.FileId, err) |
|||
} |
|||
defer readCloser.Close() |
|||
|
|||
var host string |
|||
|
|||
if err := fs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { |
|||
|
|||
request := &filer_pb.AssignVolumeRequest{ |
|||
Count: 1, |
|||
Replication: fs.replication, |
|||
Collection: fs.collection, |
|||
TtlSec: fs.ttlSec, |
|||
DataCenter: fs.dataCenter, |
|||
} |
|||
|
|||
resp, err := client.AssignVolume(context.Background(), request) |
|||
if err != nil { |
|||
glog.V(0).Infof("assign volume failure %v: %v", request, err) |
|||
return err |
|||
} |
|||
|
|||
fileId, host = resp.FileId, resp.Url |
|||
|
|||
return nil |
|||
}); err != nil { |
|||
return "", fmt.Errorf("filerGrpcAddress assign volume: %v", err) |
|||
} |
|||
|
|||
fileUrl := fmt.Sprintf("http://%s/%s", host, fileId) |
|||
|
|||
glog.V(3).Infof("replicating %s to %s header:%+v", filename, fileUrl, header) |
|||
|
|||
uploadResult, err := operation.Upload(fileUrl, filename, readCloser, |
|||
"gzip" == header.Get("Content-Encoding"), header.Get("Content-Type"), nil, "") |
|||
if err != nil { |
|||
glog.V(0).Infof("upload data %v to %s: %v", filename, fileUrl, err) |
|||
return "", fmt.Errorf("upload data: %v", err) |
|||
} |
|||
if uploadResult.Error != "" { |
|||
glog.V(0).Infof("upload failure %v to %s: %v", filename, fileUrl, err) |
|||
return "", fmt.Errorf("upload result: %v", uploadResult.Error) |
|||
} |
|||
|
|||
return |
|||
} |
|||
|
|||
func (fs *FilerSink) withFilerClient(fn func(filer_pb.SeaweedFilerClient) error) error { |
|||
|
|||
grpcConnection, err := util.GrpcDial(fs.grpcAddress) |
|||
if err != nil { |
|||
return fmt.Errorf("fail to dial %s: %v", fs.grpcAddress, err) |
|||
} |
|||
defer grpcConnection.Close() |
|||
|
|||
client := filer_pb.NewSeaweedFilerClient(grpcConnection) |
|||
|
|||
return fn(client) |
|||
} |
|||
|
|||
func volumeId(fileId string) string { |
|||
lastCommaIndex := strings.LastIndex(fileId, ",") |
|||
if lastCommaIndex > 0 { |
|||
return fileId[:lastCommaIndex] |
|||
} |
|||
return fileId |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue