DB RPC driver: add master/replica support (#17792)

Automatic Merge
Этот коммит содержится в:
Agniva De Sarker
2021-06-17 21:10:22 +05:30
коммит произвёл GitHub
родитель 030543fed9
Коммит 79d4e9e9a9
6 изменённых файлов: 37 добавлений и 19 удалений

Просмотреть файл

@@ -32,8 +32,10 @@ func (p *MyPlugin) MessageWillBePosted(_ *plugin.Context, _ *model.Post) (*model
store := sqlstore.New(p.API.GetUnsanitizedConfig().SqlSettings, nil) store := sqlstore.New(p.API.GetUnsanitizedConfig().SqlSettings, nil)
store.GetMaster().Db.Close() store.GetMaster().Db.Close()
store.GetMaster().Db = sql.OpenDB(driver.NewConnector(p.Driver)) for _, isMaster := range []bool{true, false} {
defer store.GetMaster().Db.Close() // We replace the master DB with master and replica both just to make
// gorp APIs work.
store.GetMaster().Db = sql.OpenDB(driver.NewConnector(p.Driver, isMaster))
// Testing with a handful of stores // Testing with a handful of stores
storetest.TestPostStore(p.t, store, store) storetest.TestPostStore(p.t, store, store)
@@ -42,6 +44,9 @@ func (p *MyPlugin) MessageWillBePosted(_ *plugin.Context, _ *model.Post) (*model
storetest.TestChannelStore(p.t, store, store) storetest.TestChannelStore(p.t, store, store)
storetest.TestBotStore(p.t, store, store) storetest.TestBotStore(p.t, store, store)
store.GetMaster().Db.Close()
}
// Use the API to instantiate the driver // Use the API to instantiate the driver
// And then run the full suite of tests. // And then run the full suite of tests.
return nil, "OK" return nil, "OK"

Просмотреть файл

@@ -39,8 +39,12 @@ func NewDriverImpl(s *Server) *DriverImpl {
} }
} }
func (d *DriverImpl) Conn() (string, error) { func (d *DriverImpl) Conn(isMaster bool) (string, error) {
conn, err := d.s.sqlStore.GetMaster().Db.Conn(context.Background()) dbFunc := d.s.sqlStore.GetMaster
if !isMaster {
dbFunc = d.s.sqlStore.GetReplica
}
conn, err := dbFunc().Db.Conn(context.Background())
if err != nil { if err != nil {
return "", err return "", err
} }

Просмотреть файл

@@ -56,6 +56,7 @@ func (p *MattermostPlugin) SetHelpers(helpers Helpers) {
p.Helpers = helpers p.Helpers = helpers
} }
// SetDriver sets the RPC client implementation to talk with the server.
func (p *MattermostPlugin) SetDriver(driver Driver) { func (p *MattermostPlugin) SetDriver(driver Driver) {
p.Driver = driver p.Driver = driver
} }

Просмотреть файл

@@ -42,9 +42,9 @@ type Z_DbBoolReturn struct {
A bool A bool
} }
func (db *dbRPCClient) Conn() (string, error) { func (db *dbRPCClient) Conn(isMaster bool) (string, error) {
ret := &Z_DbStrErrReturn{} ret := &Z_DbStrErrReturn{}
err := db.client.Call("Plugin.Conn", struct{}{}, ret) err := db.client.Call("Plugin.Conn", isMaster, ret)
if err != nil { if err != nil {
log.Printf("error during Plugin.Conn: %v", err) log.Printf("error during Plugin.Conn: %v", err)
} }
@@ -52,8 +52,8 @@ func (db *dbRPCClient) Conn() (string, error) {
return ret.A, ret.B return ret.A, ret.B
} }
func (db *dbRPCServer) Conn(_ struct{}, ret *Z_DbStrErrReturn) error { func (db *dbRPCServer) Conn(isMaster bool, ret *Z_DbStrErrReturn) error {
ret.A, ret.B = db.dbImpl.Conn() ret.A, ret.B = db.dbImpl.Conn(isMaster)
ret.B = encodableError(ret.B) ret.B = encodableError(ret.B)
return nil return nil
} }

Просмотреть файл

@@ -109,9 +109,13 @@ type ResultContainer struct {
RowsAffectedError error RowsAffectedError error
} }
// Driver is a sql driver interface that is used by plugins to perform
// raw SQL queries without opening DB connections by themselves. This interface
// is not subject to backward compatibility guarantees and is only meant to be
// used by plugins built by the Mattermost team.
type Driver interface { type Driver interface {
// Connection // Connection
Conn() (string, error) Conn(isMaster bool) (string, error)
ConnPing(connID string) error ConnPing(connID string) error
ConnClose(connID string) error ConnClose(connID string) error
ConnQuery(connID, q string, args []driver.NamedValue) (string, error) // rows ConnQuery(connID, q string, args []driver.NamedValue) (string, error) // rows

Просмотреть файл

@@ -24,14 +24,18 @@ var (
// communicate with the DB API. // communicate with the DB API.
type Connector struct { type Connector struct {
api plugin.Driver api plugin.Driver
isMaster bool
} }
func NewConnector(api plugin.Driver) *Connector { // NewConnector returns a DB connector that can be used to return a sql.DB object.
return &Connector{api: api} // It takes a plugin.Driver implementation and a boolean flag to indicate whether
// to connect to a master or replica DB instance.
func NewConnector(api plugin.Driver, isMaster bool) *Connector {
return &Connector{api: api, isMaster: isMaster}
} }
func (c *Connector) Connect(_ context.Context) (driver.Conn, error) { func (c *Connector) Connect(_ context.Context) (driver.Conn, error) {
connID, err := c.api.Conn() connID, err := c.api.Conn(c.isMaster)
if err != nil { if err != nil {
return nil, err return nil, err
} }