app/platform: fix an issue about accessing to a closed db on shutdown (#21549)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
b31e6f2149
Коммит
c6b6b3313e
@@ -21,8 +21,8 @@ func (ps *PlatformService) Go(f func()) {
|
||||
}()
|
||||
}
|
||||
|
||||
// WaitForGoroutines blocks until all goroutines created by App.Go exit.
|
||||
func (ps *PlatformService) WaitForGoroutines() {
|
||||
// waitForGoroutines blocks until all goroutines created by PlatformService.Go() exit.
|
||||
func (ps *PlatformService) waitForGoroutines() {
|
||||
for atomic.LoadInt32(&ps.goroutineCount) != 0 {
|
||||
<-ps.goroutineExitSignal
|
||||
}
|
||||
|
||||
@@ -390,6 +390,12 @@ func (ps *PlatformService) Shutdown() error {
|
||||
|
||||
ps.RemoveLicenseListener(ps.licenseListenerId)
|
||||
|
||||
// we need to wait the goroutines to finish before closing the store
|
||||
// and this needs to be called after hub stop because hub generates goroutines
|
||||
// when it is active. If we wait first we have no mechanism to prevent adding
|
||||
// more go routines hence they still going to be invoked.
|
||||
ps.waitForGoroutines()
|
||||
|
||||
if ps.Store != nil {
|
||||
ps.Store.Close()
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/config"
|
||||
"github.com/mattermost/mattermost-server/v6/einterfaces/mocks"
|
||||
@@ -154,3 +157,24 @@ func TestMetrics(t *testing.T) {
|
||||
mockMetricsImpl.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestShutdown(t *testing.T) {
|
||||
t.Run("should shutdown gracefully", func(t *testing.T) {
|
||||
th := Setup(t)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
// we create plenty of go routines to make sure we wait for all of them
|
||||
// to finish before shutting down
|
||||
for i := 0; i < 1000; i++ {
|
||||
th.Service.Go(func() {
|
||||
time.Sleep(time.Millisecond * time.Duration(rand.Intn(20)))
|
||||
})
|
||||
}
|
||||
|
||||
err := th.Service.Shutdown()
|
||||
require.NoError(t, err)
|
||||
|
||||
// assert that there are no more go routines running
|
||||
require.Zero(t, atomic.LoadInt32(&th.Service.goroutineCount))
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user