diff --git a/cmd/dfget/app/root.go b/cmd/dfget/app/root.go index eeae7c298..a3567a8b6 100644 --- a/cmd/dfget/app/root.go +++ b/cmd/dfget/app/root.go @@ -39,6 +39,7 @@ import ( var ( localLimit string totalLimit string + minRate string filter string ) @@ -132,6 +133,10 @@ func initProperties() { cfg.LocalLimit = properties.LocalLimit } + if cfg.MinRate == 0 { + cfg.MinRate = properties.MinRate + } + if cfg.TotalLimit == 0 { cfg.TotalLimit = properties.TotalLimit } @@ -151,6 +156,10 @@ func transParams() error { return errHandler.Wrapf(errors.ErrConvertFailed, "locallimit: %v", err) } + if cfg.MinRate, err = transLimit(minRate); err != nil { + return errHandler.Wrapf(errors.ErrConvertFailed, "minrate: %v", err) + } + if cfg.TotalLimit, err = transLimit(totalLimit); err != nil { return errHandler.Wrapf(errors.ErrConvertFailed, "totallimit: %v", err) } @@ -184,9 +193,11 @@ func initFlags() { flagSet.StringVarP(&cfg.Output, "output", "o", "", "Destination path which is used to store the requested downloading file. It must contain detailed directory and specific filename, for example, '/tmp/file.mp4'") - // localLimit & totalLimit & timeout + // localLimit & minRate & totalLimit & timeout flagSet.StringVarP(&localLimit, "locallimit", "s", "", "network bandwidth rate limit for single download task, in format of 20M/m/K/k") + flagSet.StringVar(&minRate, "minrate", "", + "minimal network bandwidth rate for downloading a file, in format of 20M/m/K/k") flagSet.StringVar(&totalLimit, "totallimit", "", "network bandwidth rate limit for the whole host, in format of 20M/m/K/k") flagSet.IntVarP(&cfg.Timeout, "timeout", "e", 0, diff --git a/dfget/config/config.go b/dfget/config/config.go index 7f607c8cc..5af9f5a63 100644 --- a/dfget/config/config.go +++ b/dfget/config/config.go @@ -60,6 +60,9 @@ type Properties struct { // LocalLimit rate limit about a single download task,format: 20M/m/K/k. LocalLimit int `yaml:"localLimit"` + // Minimal rate about a single download task,format: 20M/m/K/k. + MinRate int `yaml:"minRate"` + // TotalLimit rate limit about the whole host,format: 20M/m/K/k. TotalLimit int `yaml:"totalLimit"` @@ -75,6 +78,7 @@ func NewProperties() *Properties { return &Properties{ Nodes: []string{DefaultNode}, LocalLimit: DefaultLocalLimit, + MinRate: DefaultMinRate, ClientQueueSize: DefaultClientQueueSize, } } @@ -139,6 +143,9 @@ type Config struct { // LocalLimit rate limit about a single download task,format: 20M/m/K/k. LocalLimit int `json:"localLimit,omitempty"` + // Minimal rate about a single download task,format: 20M/m/K/k. + MinRate int `json:"minRate,omitempty"` + // TotalLimit rate limit about the whole host,format: 20M/m/K/k. TotalLimit int `json:"totalLimit,omitempty"` diff --git a/dfget/config/constants.go b/dfget/config/constants.go index d52b600ba..15da08a3d 100644 --- a/dfget/config/constants.go +++ b/dfget/config/constants.go @@ -49,6 +49,7 @@ const ( DefaultIniConfigFile = "/etc/dragonfly.conf" DefaultNode = "127.0.0.1" DefaultLocalLimit = 20 * 1024 * 1024 + DefaultMinRate = 64 * 1024 DefaultClientQueueSize = 6 ) diff --git a/dfget/core/core.go b/dfget/core/core.go index 3fd7b05d7..6649b37d7 100644 --- a/dfget/core/core.go +++ b/dfget/core/core.go @@ -168,7 +168,7 @@ func downloadFile(cfg *config.Config, supernodeAPI api.SupernodeAPI, getter = p2pDown.NewP2PDownloader(cfg, supernodeAPI, register, result) } - timeout := calculateTimeout(cfg.RV.FileLength, cfg.Timeout) + timeout := calculateTimeout(cfg.RV.FileLength, cfg.Timeout, cfg.MinRate) err := downloader.DoDownloadTimeout(getter, timeout) success := "SUCCESS" if err != nil { @@ -260,13 +260,13 @@ func checkConnectSupernode(nodes []string) (localIP string) { return "" } -func calculateTimeout(fileLength int64, defaultTimeoutSecond int) time.Duration { +func calculateTimeout(fileLength int64, defaultTimeoutSecond int, minRate int) time.Duration { timeout := 5 * 60 if defaultTimeoutSecond > 0 { timeout = defaultTimeoutSecond } else if fileLength > 0 { - timeout = int(fileLength/(64*1024) + 10) + timeout = int(fileLength/int64(minRate) + 10) } return time.Duration(timeout) * time.Second }