Переглянути джерело

lib/model: Close connections when model is stopped (#5733)

Simon Frei 6 роки тому
батько
коміт
64518b0f7e
2 змінених файлів з 22 додано та 15 видалено
  1. 20 0
      lib/model/model.go
  2. 2 15
      lib/model/model_test.go

+ 20 - 0
lib/model/model.go

@@ -180,6 +180,7 @@ var (
 	// errors about why a connection is closed
 	errIgnoredFolderRemoved = errors.New("folder no longer ignored")
 	errReplacingConnection  = errors.New("replacing connection")
+	errStopped              = errors.New("Syncthing is being stopped")
 )
 
 // NewModel creates and starts a new model. The model starts in read-only mode,
@@ -225,6 +226,25 @@ func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersio
 	return m
 }
 
+func (m *model) Stop() {
+	m.Supervisor.Stop()
+	devs := m.cfg.Devices()
+	ids := make([]protocol.DeviceID, 0, len(devs))
+	for id := range devs {
+		ids = append(ids, id)
+	}
+	m.pmut.RLock()
+	closed := make([]chan struct{}, 0, len(m.closed))
+	for _, c := range m.closed {
+		closed = append(closed, c)
+	}
+	m.pmut.RUnlock()
+	m.closeConns(ids, errStopped)
+	for _, c := range closed {
+		<-c
+	}
+}
+
 // StartDeadlockDetector starts a deadlock detector on the models locks which
 // causes panics in case the locks cannot be acquired in the given timeout
 // period.

+ 2 - 15
lib/model/model_test.go

@@ -862,15 +862,6 @@ func TestIssue5063(t *testing.T) {
 	m := newState(defaultAutoAcceptCfg)
 	defer cleanupModel(m)
 
-	m.pmut.Lock()
-	for _, c := range m.conn {
-		conn := c.(*fakeConnection)
-		conn.mut.Lock()
-		conn.closeFn = func(_ error) {}
-		conn.mut.Unlock()
-	}
-	m.pmut.Unlock()
-
 	wg := sync.WaitGroup{}
 
 	addAndVerify := func(id string) {
@@ -3267,12 +3258,7 @@ func TestSanitizePath(t *testing.T) {
 func TestConnCloseOnRestart(t *testing.T) {
 	w, fcfg := tmpDefaultWrapper()
 	m := setupModel(w)
-	defer func() {
-		m.Stop()
-		m.db.Close()
-		os.RemoveAll(fcfg.Filesystem().URI())
-		os.Remove(w.ConfigPath())
-	}()
+	defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI())
 
 	br := &testutils.BlockingRW{}
 	nw := &testutils.NoopRW{}
@@ -3291,6 +3277,7 @@ func TestConnCloseOnRestart(t *testing.T) {
 		t.Fatal("Timed out before folder restart returned")
 	}
 	m.pmut.RLock()
+	defer m.pmut.RUnlock()
 	if len(m.conn) != 0 {
 		t.Errorf("Conn wasn't removed on restart (len(m.conn) == %v)", len(m.conn))
 	}