Repository: dragonflyoss/Dragonfly2
Pull request #1283 (2022-04-27 04:41:23)

fix: legacy cdn peer
Signed-off-by: Gaius <gaius.qi@gmail.com>

<!--- Provide a general summary of your changes in the Title above -->

## Description
- If cdn server's task has left and did not notify the schduler to leave the task, scheduler sets cdn peer state to `PeerStateLeave`.
<!--- 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: -->

- [ ] 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! -->

- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the **CONTRIBUTING** document.
- [ ] I have added tests to cover my changes.



Patch:
diff --git a/scheduler/service/service.go b/scheduler/service/service.go
index feccf596..5a3a7ffb 100644
--- a/scheduler/service/service.go
+++ b/scheduler/service/service.go
@@ -672,7 +672,7 @@ func (s *Service) handlePieceFail(ctx context.Context, peer *resource.Peer, piec
 		peer.Log.Infof("parent %s is cdn", piece.DstPid)
 		fallthrough
 	case base.Code_CDNTaskNotFound:
-		s.handlePeerFail(ctx, parent)
+		s.handleLegacyCDNPeer(ctx, parent)
 
 		// Start trigger cdn task
 		if s.config.CDN.Enable {
@@ -738,6 +738,32 @@ func (s *Service) handlePeerFail(ctx context.Context, peer *resource.Peer) {
 	})
 }
 
+// handleLegacyCDNPeer handles cdn server's task has left,
+// but did not notify the schduler to leave the task
+func (s *Service) handleLegacyCDNPeer(ctx context.Context, peer *resource.Peer) {
+	if err := peer.FSM.Event(resource.PeerEventDownloadFailed); err != nil {
+		peer.Log.Errorf("peer fsm event failed: %s", err.Error())
+		return
+	}
+
+	if err := peer.FSM.Event(resource.PeerEventLeave); err != nil {
+		peer.Log.Errorf("peer fsm event failed: %s", err.Error())
+		return
+	}
+
+	// Reschedule a new parent to children of peer to exclude the current failed peer
+	peer.Children.Range(func(_, value interface{}) bool {
+		child, ok := value.(*resource.Peer)
+		if !ok {
+			return true
+		}
+
+		child.Log.Infof("schedule parent because of parent peer %s is failed", peer.ID)
+		s.scheduler.ScheduleParent(ctx, child, child.BlockPeers)
+		return true
+	})
+}
+
 // Conditions for the task to switch to the TaskStateSucceeded are:
 // 1. CDN downloads the resource successfully
 // 2. Dfdaemon back-to-source to download successfully


Test patch:
diff --git a/scheduler/service/service_test.go b/scheduler/service/service_test.go
index 97561c05..db0eeb68 100644
--- a/scheduler/service/service_test.go
+++ b/scheduler/service/service_test.go
@@ -2583,7 +2583,7 @@ func TestService_handlePieceFail(t *testing.T) {
 
 				svc.handlePieceFail(context.Background(), peer, piece)
 				assert := assert.New(t)
-				assert.True(parent.FSM.Is(resource.PeerStateFailed))
+				assert.True(parent.FSM.Is(resource.PeerStateLeave))
 			},
 		},
 		{
@@ -2613,7 +2613,7 @@ func TestService_handlePieceFail(t *testing.T) {
 				svc.handlePieceFail(context.Background(), peer, piece)
 				assert := assert.New(t)
 				assert.True(peer.FSM.Is(resource.PeerStateRunning))
-				assert.True(parent.FSM.Is(resource.PeerStateFailed))
+				assert.True(parent.FSM.Is(resource.PeerStateLeave))
 			},
 		},
 		{