Explorar o código

for limit upload speed,modified according to review comments

taowei.wtw %!s(int64=6) %!d(string=hai) anos
pai
achega
35ccc29542
Modificáronse 9 ficheiros con 149 adicións e 74 borrados
  1. 3 0
      .travis.yml
  2. 0 23
      oss/band_limt_reader_1_6.go
  3. 92 25
      oss/bucket_test.go
  4. 1 1
      oss/client.go
  5. 1 1
      oss/client_test.go
  6. 8 8
      oss/conf.go
  7. 2 2
      oss/conn.go
  8. 28 0
      oss/limit_reader_1_6.go
  9. 14 14
      oss/limit_reader_1_7.go

+ 3 - 0
.travis.yml

@@ -10,6 +10,9 @@ install:
 - go get gopkg.in/check.v1
 - go get github.com/satori/go.uuid
 - go get github.com/baiyubin/aliyun-sts-go-sdk/sts
+
+- if [[ $TRAVIS_GO_VERSION = '1.7' || $TRAVIS_GO_VERSION > '1.7' ]]; then go get golang.org/x/time/rate ; fi
+ 
 script:
 - cd oss
 - travis_wait 30 go test -v -covermode=count -coverprofile=coverage.out -timeout=30m

+ 0 - 23
oss/band_limt_reader_1_6.go

@@ -1,23 +0,0 @@
-// +build !go1.7
-
-// "golang.org/x/time/rate" is depended on golang context package  go1.7 onward
-package oss
-
-import (
-	"fmt"
-)
-
-const (
-	perTokenBandSize int = 1024
-)
-
-type OssLimiter struct {
-}
-
-type BandLimitReader struct {
-}
-
-func GetOssLimiter(bandSpeed int) (ossLimiter *OssLimiter, err error) {
-	err = fmt.Errorf("rate.Limiter is not supported below version go1.7")
-	return nil, err
-}

+ 92 - 25
oss/bucket_test.go

@@ -43,7 +43,6 @@ func (s *OssBucketSuite) SetUpSuite(c *C) {
 
 	s.client.CreateBucket(bucketName)
 
-	archiveBucketName := bucketName + "-archive"
 	err = s.client.CreateBucket(archiveBucketName, StorageClass(StorageArchive))
 	c.Assert(err, IsNil)
 
@@ -60,7 +59,6 @@ func (s *OssBucketSuite) SetUpSuite(c *C) {
 	testLogger.Println("test bucket started")
 }
 
-
 // TearDownSuite runs before each test or benchmark starts running.
 func (s *OssBucketSuite) TearDownSuite(c *C) {
 	for _, bucket := range []*Bucket{s.bucket, s.archiveBucket} {
@@ -2289,7 +2287,7 @@ func (s *OssBucketSuite) detectUploadSpeed(bucket *Bucket, c *C) (upSpeed int) {
 
 	// byte/s
 	upSpeed = len(textBuffer) * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
-	return
+	return upSpeed
 }
 
 func (s *OssBucketSuite) TestPutSingleObjectLimitSpeed(c *C) {
@@ -2319,15 +2317,15 @@ func (s *OssBucketSuite) TestPutSingleObjectLimitSpeed(c *C) {
 	detectSpeed := s.detectUploadSpeed(bucket, c)
 
 	var limitSpeed = 0
-	if detectSpeed <= perTokenBandSize*2 {
-		limitSpeed = perTokenBandSize
+	if detectSpeed <= perTokenBandwidthSize*2 {
+		limitSpeed = perTokenBandwidthSize
 	} else {
 		//this situation, the test works better
 		limitSpeed = detectSpeed / 2
 	}
 
 	// KB/s
-	err = client.LimitUploadSpeed(limitSpeed / perTokenBandSize)
+	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
 	c.Assert(err, IsNil)
 
 	objectName := objectNamePrefix + getUuid()
@@ -2346,8 +2344,8 @@ func (s *OssBucketSuite) TestPutSingleObjectLimitSpeed(c *C) {
 
 	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
 
-	if detectSpeed > perTokenBandSize {
-		// the minimum uploas limit speed is perTokenBandSize(1024 byte/s)
+	if detectSpeed > perTokenBandwidthSize {
+		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
 		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
 	}
 
@@ -2401,14 +2399,14 @@ func (s *OssBucketSuite) TestPutManyObjectLimitSpeed(c *C) {
 	//detect speed:byte/s
 	detectSpeed := s.detectUploadSpeed(bucket, c)
 	var limitSpeed = 0
-	if detectSpeed <= perTokenBandSize*2 {
-		limitSpeed = perTokenBandSize
+	if detectSpeed <= perTokenBandwidthSize*2 {
+		limitSpeed = perTokenBandwidthSize
 	} else {
 		limitSpeed = detectSpeed / 2
 	}
 
 	// KB/s
-	err = client.LimitUploadSpeed(limitSpeed / perTokenBandSize)
+	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
 	c.Assert(err, IsNil)
 
 	// object1
@@ -2437,8 +2435,8 @@ func (s *OssBucketSuite) TestPutManyObjectLimitSpeed(c *C) {
 	realSpeed := len(textBuffer) * 2 * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
 	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
 
-	if detectSpeed > perTokenBandSize {
-		// the minimum uploas limit speed is perTokenBandSize(1024 byte/s)
+	if detectSpeed > perTokenBandwidthSize {
+		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
 		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
 	}
 	c.Assert(sum, Equals, 2)
@@ -2493,15 +2491,15 @@ func (s *OssBucketSuite) TestPutMultipartObjectLimitSpeed(c *C) {
 	detectSpeed := s.detectUploadSpeed(bucket, c)
 
 	var limitSpeed = 0
-	if detectSpeed <= perTokenBandSize*2 {
-		limitSpeed = perTokenBandSize
+	if detectSpeed <= perTokenBandwidthSize*2 {
+		limitSpeed = perTokenBandwidthSize
 	} else {
 		//this situation, the test works better
 		limitSpeed = detectSpeed / 2
 	}
 
 	// KB/s
-	err = client.LimitUploadSpeed(limitSpeed / perTokenBandSize)
+	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
 	c.Assert(err, IsNil)
 
 	objectName := objectNamePrefix + getUuid()
@@ -2510,7 +2508,7 @@ func (s *OssBucketSuite) TestPutMultipartObjectLimitSpeed(c *C) {
 	// 1M byte
 	fileSize := 0
 	textBuffer := randStr(1024 * 1024)
-	if detectSpeed < perTokenBandSize {
+	if detectSpeed < perTokenBandwidthSize {
 		ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
 		f, err := os.Stat(fileName)
 		c.Assert(err, IsNil)
@@ -2545,8 +2543,8 @@ func (s *OssBucketSuite) TestPutMultipartObjectLimitSpeed(c *C) {
 	realSpeed := fileSize * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
 	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
 
-	if detectSpeed > perTokenBandSize {
-		// the minimum uploas limit speed is perTokenBandSize(1024 byte/s)
+	if detectSpeed > perTokenBandwidthSize {
+		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
 		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
 	}
 
@@ -2596,15 +2594,15 @@ func (s *OssBucketSuite) TestPutObjectFromFileLimitSpeed(c *C) {
 	detectSpeed := s.detectUploadSpeed(bucket, c)
 
 	var limitSpeed = 0
-	if detectSpeed <= perTokenBandSize*2 {
-		limitSpeed = perTokenBandSize
+	if detectSpeed <= perTokenBandwidthSize*2 {
+		limitSpeed = perTokenBandwidthSize
 	} else {
 		//this situation, the test works better
 		limitSpeed = detectSpeed / 2
 	}
 
 	// KB/s
-	err = client.LimitUploadSpeed(limitSpeed / perTokenBandSize)
+	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
 	c.Assert(err, IsNil)
 
 	objectName := objectNamePrefix + getUuid()
@@ -2613,7 +2611,7 @@ func (s *OssBucketSuite) TestPutObjectFromFileLimitSpeed(c *C) {
 	// 1M byte
 	fileSize := 0
 	textBuffer := randStr(1024 * 1024)
-	if detectSpeed < perTokenBandSize {
+	if detectSpeed < perTokenBandwidthSize {
 		ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
 		f, err := os.Stat(fileName)
 		c.Assert(err, IsNil)
@@ -2648,8 +2646,8 @@ func (s *OssBucketSuite) TestPutObjectFromFileLimitSpeed(c *C) {
 	realSpeed := fileSize * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
 	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
 
-	if detectSpeed > perTokenBandSize {
-		// the minimum uploas limit speed is perTokenBandSize(1024 byte/s)
+	if detectSpeed > perTokenBandwidthSize {
+		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
 		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
 	}
 
@@ -2672,3 +2670,72 @@ func (s *OssBucketSuite) TestPutObjectFromFileLimitSpeed(c *C) {
 
 	return
 }
+
+// upload speed limit parameters will not affect download speed
+func (s *OssBucketSuite) TestUploadObjectLimitSpeed(c *C) {
+	// create limit client and bucket
+	client, err := New(endpoint, accessID, accessKey)
+	c.Assert(err, IsNil)
+
+	tokenCount := 1
+	err = client.LimitUploadSpeed(tokenCount)
+	if err != nil {
+		// go version is less than go1.7,not support limit upload speed
+		// doesn't run this test
+		return
+	} else {
+		// set unlimited
+		client.LimitUploadSpeed(0)
+	}
+
+	bucketName := bucketNamePrefix + randLowStr(5)
+	err = client.CreateBucket(bucketName)
+	c.Assert(err, IsNil)
+
+	bucket, err := client.Bucket(bucketName)
+	c.Assert(err, IsNil)
+
+	//first:upload a object
+	textBuffer := randStr(1024 * 100)
+	objectName := objectNamePrefix + getUuid()
+	err = bucket.PutObject(objectName, strings.NewReader(textBuffer))
+	c.Assert(err, IsNil)
+
+	// limit upload speed
+	err = client.LimitUploadSpeed(tokenCount)
+	c.Assert(err, IsNil)
+
+	// then download the object
+	startT := time.Now()
+	body, err := bucket.GetObject(objectName)
+	c.Assert(err, IsNil)
+
+	str, err := readBody(body)
+	c.Assert(err, IsNil)
+	endT := time.Now()
+
+	c.Assert(str, Equals, textBuffer)
+
+	// byte/s
+	downloadSpeed := len(textBuffer) * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
+
+	// upload speed limit parameters will not affect download speed
+	c.Assert(downloadSpeed > 2*tokenCount*perTokenBandwidthSize, Equals, true)
+
+	bucket.DeleteObject(objectName)
+	client.DeleteBucket(bucketName)
+}
+
+// test LimitUploadSpeed failure
+func (s *OssBucketSuite) TestLimitUploadSpeedFail(c *C) {
+	// create limit client and bucket
+	client, err := New(endpoint, accessID, accessKey)
+	c.Assert(err, IsNil)
+
+	err = client.LimitUploadSpeed(-1)
+	c.Assert(err, NotNil)
+
+	client.Config = nil
+	err = client.LimitUploadSpeed(100)
+	c.Assert(err, NotNil)
+}

+ 1 - 1
oss/client.go

@@ -650,7 +650,7 @@ func (client Client) GetBucketInfo(bucketName string) (GetBucketInfoResult, erro
 	return out, err
 }
 
-// LimitUploadSpeed: set upload band limit speed,default is 0,unlimited
+// LimitUploadSpeed: set upload bandwidth limit speed,default is 0,unlimited
 // upSpeed: KB/s, 0 is unlimited,default is 0
 // error:it's nil if success, otherwise failure
 func (client Client) LimitUploadSpeed(upSpeed int) error {

+ 1 - 1
oss/client_test.go

@@ -1595,7 +1595,7 @@ func (s *OssClientSuite) TestHttpLogSignUrl(c *C) {
 	client.DeleteBucket(testBucketName)
 }
 
-func (s *OssClientSuite) TestLimitUploadSpeed(c *C) {
+func (s *OssClientSuite) TestSetLimitUploadSpeed(c *C) {
 	client, err := New(endpoint, accessID, accessKey)
 	c.Assert(err, IsNil)
 

+ 8 - 8
oss/conf.go

@@ -53,26 +53,26 @@ type Config struct {
 	IsEnableMD5      bool         // Flag of enabling MD5 for upload.
 	MD5Threshold     int64        // Memory footprint threshold for each MD5 computation (16MB is the default), in byte. When the data is more than that, temp file is used.
 	IsEnableCRC      bool         // Flag of enabling CRC for upload.
-	UploadLimitSpeed int          // Upload limit speed:KB/s, 0 is unlimited
-	UploadLimiter    *OssLimiter  // Band limit reader for upload
 	LogLevel         int          // Log level
 	Logger           *log.Logger  // For write log
+	UploadLimitSpeed int          // Upload limit speed:KB/s, 0 is unlimited
+	UploadLimiter    *OssLimiter  // Bandwidth limit reader for upload
 }
 
-// LimitUploadSpeed, upSpeed:KB/s, 0 is unlimited,default is 0
-func (config *Config) LimitUploadSpeed(upSpeed int) error {
-	if upSpeed < 0 {
+// LimitUploadSpeed, uploadSpeed:KB/s, 0 is unlimited,default is 0
+func (config *Config) LimitUploadSpeed(uploadSpeed int) error {
+	if uploadSpeed < 0 {
 		return fmt.Errorf("erro,speed is less than 0")
-	} else if upSpeed == 0 {
+	} else if uploadSpeed == 0 {
 		config.UploadLimitSpeed = 0
 		config.UploadLimiter = nil
 		return nil
 	}
 
 	var err error
-	config.UploadLimiter, err = GetOssLimiter(upSpeed)
+	config.UploadLimiter, err = GetOssLimiter(uploadSpeed)
 	if err == nil {
-		config.UploadLimitSpeed = upSpeed
+		config.UploadLimitSpeed = uploadSpeed
 	}
 	return err
 }

+ 2 - 2
oss/conn.go

@@ -367,7 +367,7 @@ func (conn Conn) handleBody(req *http.Request, body io.Reader, initCRC uint64,
 	}
 
 	if conn.isUploadLimitReq(req) {
-		limitReader := &BandLimitReader{
+		limitReader := &LimitSpeedReader{
 			reader:     rc,
 			ossLimiter: conn.config.UploadLimiter,
 		}
@@ -384,7 +384,7 @@ func (conn Conn) isUploadLimitReq(req *http.Request) bool {
 		return false
 	}
 
-	if req.Method != http.MethodGet && req.Method != http.MethodDelete && req.Method != http.MethodHead {
+	if req.Method != "GET" && req.Method != "DELETE" && req.Method != "HEAD" {
 		if req.ContentLength > 0 {
 			return true
 		}

+ 28 - 0
oss/limit_reader_1_6.go

@@ -0,0 +1,28 @@
+// +build !go1.7
+
+// "golang.org/x/time/rate" is depended on golang context package  go1.7 onward
+// this file is only for build,not supports limit upload speed
+package oss
+
+import (
+	"fmt"
+	"io"
+)
+
+const (
+	perTokenBandwidthSize int = 1024
+)
+
+type OssLimiter struct {
+}
+
+type LimitSpeedReader struct {
+	io.ReadCloser
+	reader     io.Reader
+	ossLimiter *OssLimiter
+}
+
+func GetOssLimiter(uploadSpeed int) (ossLimiter *OssLimiter, err error) {
+	err = fmt.Errorf("rate.Limiter is not supported below version go1.7")
+	return nil, err
+}

+ 14 - 14
oss/band_limit_reader.go → oss/limit_reader_1_7.go

@@ -12,7 +12,7 @@ import (
 )
 
 const (
-	perTokenBandSize int = 1024
+	perTokenBandwidthSize int = 1024
 )
 
 // OssLimiter: wrapper rate.Limiter
@@ -21,27 +21,27 @@ type OssLimiter struct {
 }
 
 // GetOssLimiter:create OssLimiter
-// bandSpeed:KB/s
-func GetOssLimiter(bandSpeed int) (ossLimiter *OssLimiter, err error) {
-	limiter := rate.NewLimiter(rate.Limit(bandSpeed), bandSpeed)
+// uploadSpeed:KB/s
+func GetOssLimiter(uploadSpeed int) (ossLimiter *OssLimiter, err error) {
+	limiter := rate.NewLimiter(rate.Limit(uploadSpeed), uploadSpeed)
 
 	// first consume the initial full token,the limiter will behave more accurately
-	limiter.AllowN(time.Now(), bandSpeed)
+	limiter.AllowN(time.Now(), uploadSpeed)
 
 	return &OssLimiter{
 		limiter: limiter,
 	}, nil
 }
 
-// BandLimitReader: for limit band upload
-type BandLimitReader struct {
+// LimitSpeedReader: for limit bandwidth upload
+type LimitSpeedReader struct {
 	io.ReadCloser
 	reader     io.Reader
 	ossLimiter *OssLimiter
 }
 
 // Read
-func (r *BandLimitReader) Read(p []byte) (n int, err error) {
+func (r *LimitSpeedReader) Read(p []byte) (n int, err error) {
 	n = 0
 	err = nil
 	start := 0
@@ -50,8 +50,8 @@ func (r *BandLimitReader) Read(p []byte) (n int, err error) {
 	var tmpN int
 	var tc int
 	for start < len(p) {
-		if start+burst*perTokenBandSize < len(p) {
-			end = start + burst*perTokenBandSize
+		if start+burst*perTokenBandwidthSize < len(p) {
+			end = start + burst*perTokenBandwidthSize
 		} else {
 			end = len(p)
 		}
@@ -66,12 +66,12 @@ func (r *BandLimitReader) Read(p []byte) (n int, err error) {
 			return
 		}
 
-		tc = int(math.Ceil(float64(tmpN) / float64(perTokenBandSize)))
+		tc = int(math.Ceil(float64(tmpN) / float64(perTokenBandwidthSize)))
 		now := time.Now()
 		re := r.ossLimiter.limiter.ReserveN(now, tc)
 		if !re.OK() {
-			err = fmt.Errorf("ReserveN error,start:%d,end:%d,burst:%d,perTokenBandSize:%d",
-				start, end, burst, perTokenBandSize)
+			err = fmt.Errorf("LimitSpeedReader.Read() failure,ReserveN error,start:%d,end:%d,burst:%d,perTokenBandwidthSize:%d",
+				start, end, burst, perTokenBandwidthSize)
 			return
 		} else {
 			timeDelay := re.Delay()
@@ -82,7 +82,7 @@ func (r *BandLimitReader) Read(p []byte) (n int, err error) {
 }
 
 // Close ...
-func (r *BandLimitReader) Close() error {
+func (r *LimitSpeedReader) Close() error {
 	rc, ok := r.reader.(io.ReadCloser)
 	if ok {
 		return rc.Close()