fix: database switching may do nothing

This commit is contained in:
Lykin 2024-01-02 00:34:48 +08:00
parent d2bb2995c5
commit 660fc0cf93
1 changed files with 35 additions and 34 deletions

View File

@ -81,7 +81,9 @@ func (b *browserService) Start(ctx context.Context) {
func (b *browserService) Stop() { func (b *browserService) Stop() {
for _, item := range b.connMap { for _, item := range b.connMap {
if item.client != nil { if item.client != nil {
item.cancelFunc() if item.cancelFunc != nil {
item.cancelFunc()
}
item.client.Close() item.client.Close()
} }
} }
@ -227,7 +229,9 @@ func (b *browserService) CloseConnection(name string) (resp types.JSResp) {
if ok { if ok {
delete(b.connMap, name) delete(b.connMap, name)
if item.client != nil { if item.client != nil {
item.cancelFunc() if item.cancelFunc != nil {
item.cancelFunc()
}
item.client.Close() item.client.Close()
} }
} }
@ -287,44 +291,41 @@ func (b *browserService) getRedisClient(server string, db int) (item *connection
var ok bool var ok bool
var client redis.UniversalClient var client redis.UniversalClient
if item, ok = b.connMap[server]; ok { if item, ok = b.connMap[server]; ok {
client = item.client if item.db == db {
} else {
selConn := Connection().getConnection(server)
if selConn == nil {
err = fmt.Errorf("no match connection \"%s\"", server)
return return
} }
client, err = b.createRedisClient(selConn.ConnectionConfig)
ctx, cancelFunc := context.WithCancel(b.ctx) // close previous connection if database is not the same
item = &connectionItem{ if item.cancelFunc != nil {
client: client, item.cancelFunc()
ctx: ctx,
cancelFunc: cancelFunc,
cursor: map[int]uint64{},
entryCursor: map[int]entryCursor{},
stepSize: int64(selConn.LoadSize),
} }
if item.stepSize <= 0 { item.client.Close()
item.stepSize = consts.DEFAULT_LOAD_SIZE delete(b.connMap, server)
}
b.connMap[server] = item
} }
// BUG: go-redis might not be executing commands on the corresponding database // recreate new connection after switch database
// requiring a database switch before execute each command selConn := Connection().getConnection(server)
if db >= 0 && item.db != db { if selConn == nil {
var rdb *redis.Client err = fmt.Errorf("no match connection \"%s\"", server)
if rdb, ok = client.(*redis.Client); ok && rdb != nil { return
_, err = rdb.Pipelined(item.ctx, func(pipe redis.Pipeliner) error {
return pipe.Select(item.ctx, db).Err()
})
if err != nil {
return
}
item.db = db
b.connMap[server].db = db
}
} }
var connConfig = selConn.ConnectionConfig
connConfig.LastDB = db
client, err = b.createRedisClient(connConfig)
ctx, cancelFunc := context.WithCancel(b.ctx)
item = &connectionItem{
client: client,
ctx: ctx,
cancelFunc: cancelFunc,
cursor: map[int]uint64{},
entryCursor: map[int]entryCursor{},
stepSize: int64(selConn.LoadSize),
db: db,
}
if item.stepSize <= 0 {
item.stepSize = consts.DEFAULT_LOAD_SIZE
}
b.connMap[server] = item
return return
} }