MM-56402: Introduce a pluginID to track RPC DB connections (#26424)
Previously, we relied on the plugin to close the DB connections on shutdown. While this keeps the code simple, there is no guarantee that the plugin author will remember to close the DB. In that case, it's better to track the connections from the server side and close them in case they weren't closed already. This complicates the API slightly, but it's a price we need to pay. https://mattermost.atlassian.net/browse/MM-56402 ```release-note We close any remaining unclosed DB RPC connections after a plugin shuts down. ``` Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6aaabfb376
Коммит
effb99301e
@@ -62,3 +62,14 @@ type Driver interface {
|
||||
// ResetSession(ctx context.Context) error
|
||||
// IsValid() bool
|
||||
}
|
||||
|
||||
// AppDriver is an extension of the Driver interface to capture non-RPC APIs.
|
||||
type AppDriver interface {
|
||||
Driver
|
||||
|
||||
// ConnWithPluginID is only used by the server, and isn't exposed via the RPC API.
|
||||
ConnWithPluginID(isMaster bool, pluginID string) (string, error)
|
||||
// This is an extra method needed to shutdown connections
|
||||
// after a plugin shuts down.
|
||||
ShutdownConns(pluginID string)
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ type Environment struct {
|
||||
logger *mlog.Logger
|
||||
metrics metricsInterface
|
||||
newAPIImpl apiImplCreatorFunc
|
||||
dbDriver Driver
|
||||
dbDriver AppDriver
|
||||
pluginDir string
|
||||
webappPluginDir string
|
||||
prepackagedPlugins []*PrepackagedPlugin
|
||||
@@ -64,7 +64,7 @@ type Environment struct {
|
||||
|
||||
func NewEnvironment(
|
||||
newAPIImpl apiImplCreatorFunc,
|
||||
dbDriver Driver,
|
||||
dbDriver AppDriver,
|
||||
pluginDir string,
|
||||
webappPluginDir string,
|
||||
logger *mlog.Logger,
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
|
||||
type supervisor struct {
|
||||
lock sync.RWMutex
|
||||
pluginID string
|
||||
appDriver AppDriver
|
||||
client *plugin.Client
|
||||
hooks Hooks
|
||||
implemented [TotalHooksID]bool
|
||||
@@ -31,6 +33,15 @@ type supervisor struct {
|
||||
isReattached bool
|
||||
}
|
||||
|
||||
type driverForPlugin struct {
|
||||
AppDriver
|
||||
pluginID string
|
||||
}
|
||||
|
||||
func (d *driverForPlugin) Conn(isMaster bool) (string, error) {
|
||||
return d.AppDriver.ConnWithPluginID(isMaster, d.pluginID)
|
||||
}
|
||||
|
||||
func WithExecutableFromManifest(pluginInfo *model.BundleInfo) func(*supervisor, *plugin.ClientConfig) error {
|
||||
return func(_ *supervisor, clientConfig *plugin.ClientConfig) error {
|
||||
executable := pluginInfo.Manifest.GetExecutableForRuntime(runtime.GOOS, runtime.GOARCH)
|
||||
@@ -74,8 +85,14 @@ func WithReattachConfig(pluginReattachConfig *model.PluginReattachConfig) func(*
|
||||
}
|
||||
}
|
||||
|
||||
func newSupervisor(pluginInfo *model.BundleInfo, apiImpl API, driver Driver, parentLogger *mlog.Logger, metrics metricsInterface, opts ...func(*supervisor, *plugin.ClientConfig) error) (retSupervisor *supervisor, retErr error) {
|
||||
sup := supervisor{}
|
||||
func newSupervisor(pluginInfo *model.BundleInfo, apiImpl API, driver AppDriver, parentLogger *mlog.Logger, metrics metricsInterface, opts ...func(*supervisor, *plugin.ClientConfig) error) (retSupervisor *supervisor, retErr error) {
|
||||
sup := supervisor{
|
||||
pluginID: pluginInfo.Manifest.Id,
|
||||
}
|
||||
if driver != nil {
|
||||
sup.appDriver = &driverForPlugin{AppDriver: driver, pluginID: pluginInfo.Manifest.Id}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
sup.Shutdown()
|
||||
@@ -92,7 +109,7 @@ func newSupervisor(pluginInfo *model.BundleInfo, apiImpl API, driver Driver, par
|
||||
pluginMap := map[string]plugin.Plugin{
|
||||
"hooks": &hooksPlugin{
|
||||
log: wrappedLogger,
|
||||
driverImpl: driver,
|
||||
driverImpl: sup.appDriver,
|
||||
apiImpl: &apiTimerLayer{pluginInfo.Manifest.Id, apiImpl, metrics},
|
||||
},
|
||||
}
|
||||
@@ -166,8 +183,12 @@ func (sup *supervisor) Shutdown() {
|
||||
}
|
||||
|
||||
// Wait for API RPC server and DB RPC server to exit.
|
||||
// And then shutdown conns.
|
||||
if sup.hooksClient != nil {
|
||||
sup.hooksClient.doneWg.Wait()
|
||||
if sup.appDriver != nil {
|
||||
sup.appDriver.ShutdownConns(sup.pluginID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user