Repository: dragonflyoss/Dragonfly2
Pull request #1118 (2022-03-03 06:36:47)

fix: scheduler piece cost time
Signed-off-by: Gaius <gaius.qi@gmail.com>

<!--- Provide a general summary of your changes in the Title above -->

## Description
- Fix scheduler piece cost time.
<!--- Describe your changes in detail -->

## Related Issue

<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->

## Screenshots (if appropriate)

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation Update (if none of the other choices apply)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] Code compiles correctly.
- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.


codecov-commenter: # [Codecov](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) Report
> Merging [#1118](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (b343d1a) into [main](https://codecov.io/gh/dragonflyoss/Dragonfly2/commit/d7ab7225898c440188c8d1053bdc873ceee511a7?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (d7ab722) will **decrease** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118/graphs/tree.svg?width=650&height=150&src=pr&token=PUICJYSAT7&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)

```diff
@@            Coverage Diff             @@
##             main    #1118      +/-   ##
==========================================
- Coverage   45.93%   45.91%   -0.02%     
==========================================
  Files         130      130              
  Lines        9983     9985       +2     
==========================================
- Hits         4586     4585       -1     
- Misses       4877     4880       +3     
  Partials      520      520              
```

| Flag | Coverage Δ | |
|---|---|---|
| Object-compatibility-e2etests | `?` | |
| e2etests | `?` | |
| unittests | `45.91% <100.00%> (-0.02%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) | Coverage Δ | |
|---|---|---|
| [pkg/util/timeutils/time\_utils.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-cGtnL3V0aWwvdGltZXV0aWxzL3RpbWVfdXRpbHMuZ28=) | `66.66% <100.00%> (+5.12%)` | :arrow_up: |
| [scheduler/service/service.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-c2NoZWR1bGVyL3NlcnZpY2Uvc2VydmljZS5nbw==) | `87.19% <100.00%> (ø)` | |
| [cdn/supervisor/progress/progress.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2RuL3N1cGVydmlzb3IvcHJvZ3Jlc3MvcHJvZ3Jlc3MuZ28=) | `91.04% <0.00%> (-5.98%)` | :arrow_down: |
| [client/daemon/peer/piece\_broker.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1118/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9wZWVyL3BpZWNlX2Jyb2tlci5nbw==) | `88.88% <0.00%> (+3.70%)` | :arrow_up: |


Patch:
diff --git a/pkg/util/timeutils/time_utils.go b/pkg/util/timeutils/time_utils.go
index 9bcc6faa..6538f5f2 100644
--- a/pkg/util/timeutils/time_utils.go
+++ b/pkg/util/timeutils/time_utils.go
@@ -65,3 +65,13 @@ func UnixSeconds(timeString string) int64 {
 func SecondsUnixTime(seconds int64) time.Time {
 	return time.Unix(seconds, 0)
 }
+
+// NanoToTime converts an int64 nanoseconds to a time
+func NanoToTime(nsec int64) time.Time {
+	return time.Unix(0, nsec)
+}
+
+// SubNano returns the difference between two nanoseconds
+func SubNano(x int64, y int64) int64 {
+	return NanoToTime(x).Sub(NanoToTime(y)).Nanoseconds()
+}
diff --git a/scheduler/resource/cdn.go b/scheduler/resource/cdn.go
index f8632d65..1ac3b993 100644
--- a/scheduler/resource/cdn.go
+++ b/scheduler/resource/cdn.go
@@ -33,6 +33,7 @@ import (
 	"d7y.io/dragonfly/v2/pkg/rpc/cdnsystem"
 	cdnclient "d7y.io/dragonfly/v2/pkg/rpc/cdnsystem/client"
 	rpcscheduler "d7y.io/dragonfly/v2/pkg/rpc/scheduler"
+	"d7y.io/dragonfly/v2/pkg/util/timeutils"
 	"d7y.io/dragonfly/v2/scheduler/config"
 )
 
@@ -123,8 +124,7 @@ func (c *cdn) TriggerTask(ctx context.Context, task *Task) (*Peer, *rpcscheduler
 		// Handle piece download successfully
 		peer.Log.Infof("receive piece from cdn: %#v %#v", piece, piece.PieceInfo)
 		peer.Pieces.Set(uint(piece.PieceInfo.PieceNum))
-		// TODO(244372610) CDN should set piece cost
-		peer.AppendPieceCost(0)
+		peer.AppendPieceCost(timeutils.SubNano(int64(piece.EndTime), int64(piece.BeginTime)))
 		task.StorePiece(piece.PieceInfo)
 	}
 }
diff --git a/scheduler/service/service.go b/scheduler/service/service.go
index 043e8934..9c15dbea 100644
--- a/scheduler/service/service.go
+++ b/scheduler/service/service.go
@@ -28,6 +28,7 @@ import (
 	"d7y.io/dragonfly/v2/pkg/rpc/base"
 	"d7y.io/dragonfly/v2/pkg/rpc/base/common"
 	rpcscheduler "d7y.io/dragonfly/v2/pkg/rpc/scheduler"
+	"d7y.io/dragonfly/v2/pkg/util/timeutils"
 	"d7y.io/dragonfly/v2/scheduler/config"
 	"d7y.io/dragonfly/v2/scheduler/metrics"
 	"d7y.io/dragonfly/v2/scheduler/resource"
@@ -479,7 +480,7 @@ func (s *Service) handleEndOfPiece(ctx context.Context, peer *resource.Peer) {}
 func (s *Service) handlePieceSuccess(ctx context.Context, peer *resource.Peer, piece *rpcscheduler.PieceResult) {
 	// Update peer piece info
 	peer.Pieces.Set(uint(piece.PieceInfo.PieceNum))
-	peer.AppendPieceCost(int64(piece.EndTime - piece.BeginTime))
+	peer.AppendPieceCost(timeutils.SubNano(int64(piece.EndTime), int64(piece.BeginTime)))
 
 	// When the peer downloads back-to-source,
 	// piece downloads successfully updates the task piece info


Test patch:
diff --git a/pkg/util/timeutils/time_utils_test.go b/pkg/util/timeutils/time_utils_test.go
index 99c4c689..33b5566c 100644
--- a/pkg/util/timeutils/time_utils_test.go
+++ b/pkg/util/timeutils/time_utils_test.go
@@ -139,7 +139,63 @@ func TestSecondsUnixTime(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			if got := SecondsUnixTime(tt.args); got != tt.want {
-				t.Errorf("MillisUnixTime() = %v, want %v", got, tt.want)
+				t.Errorf("SecondsUnixTime() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestNanoToTime(t *testing.T) {
+	const Layout = "2006-01-02 15:04:05"
+	sample, _ := time.ParseInLocation(Layout, "2021-01-02 12:04:05", time.Local)
+	now := time.Now()
+	tests := []struct {
+		name string
+		args int64
+		want time.Time
+	}{
+		{
+			name: "convert an int64 nanosecond to a time",
+			args: sample.UnixNano(),
+			want: sample.Local(),
+		},
+		{
+			name: "convert now",
+			args: now.UnixNano(),
+			want: time.Unix(0, now.UnixNano()),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NanoToTime(tt.args); got != tt.want {
+				t.Errorf("NanoToTime() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestSubNano(t *testing.T) {
+	now := time.Now()
+	tests := []struct {
+		name string
+		args []int64
+		want int64
+	}{
+		{
+			name: "nanoseconds are not equal",
+			args: []int64{now.Add(1 * time.Nanosecond).UnixNano(), now.UnixNano()},
+			want: 1,
+		},
+		{
+			name: "nanoseconds are equal",
+			args: []int64{now.UnixNano(), now.UnixNano()},
+			want: 0,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := SubNano(tt.args[0], tt.args[1]); got != tt.want {
+				t.Errorf("SubNano() = %v, want %v", got, tt.want)
 			}
 		})
 	}