fix: the database switch might lead to other operations becoming ineffective
This commit is contained in:
parent
b7c10b33e7
commit
d59221f11e
|
@ -51,7 +51,7 @@ type connectionItem struct {
|
||||||
|
|
||||||
type browserService struct {
|
type browserService struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
connMap map[string]connectionItem
|
connMap map[string]*connectionItem
|
||||||
cmdHistory []cmdHistoryItem
|
cmdHistory []cmdHistoryItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func Browser() *browserService {
|
||||||
if browser == nil {
|
if browser == nil {
|
||||||
onceBrowser.Do(func() {
|
onceBrowser.Do(func() {
|
||||||
browser = &browserService{
|
browser = &browserService{
|
||||||
connMap: map[string]connectionItem{},
|
connMap: map[string]*connectionItem{},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -80,21 +80,20 @@ func (b *browserService) Stop() {
|
||||||
item.client.Close()
|
item.client.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.connMap = map[string]connectionItem{}
|
b.connMap = map[string]*connectionItem{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenConnection open redis server connection
|
// OpenConnection open redis server connection
|
||||||
func (b *browserService) OpenConnection(name string) (resp types.JSResp) {
|
func (b *browserService) OpenConnection(name string) (resp types.JSResp) {
|
||||||
item, err := b.getRedisClient(name, 0)
|
// get connection config
|
||||||
|
selConn := Connection().getConnection(name)
|
||||||
|
item, err := b.getRedisClient(name, selConn.LastDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client, ctx := item.client, item.ctx
|
client, ctx := item.client, item.ctx
|
||||||
// get connection config
|
|
||||||
selConn := Connection().getConnection(name)
|
|
||||||
|
|
||||||
var totaldb int
|
var totaldb int
|
||||||
if selConn.DBFilterType == "" || selConn.DBFilterType == "none" {
|
if selConn.DBFilterType == "" || selConn.DBFilterType == "none" {
|
||||||
// get total databases
|
// get total databases
|
||||||
|
@ -222,7 +221,7 @@ func (b *browserService) CloseConnection(name string) (resp types.JSResp) {
|
||||||
|
|
||||||
// get a redis client from local cache or create a new open
|
// get a redis client from local cache or create a new open
|
||||||
// if db >= 0, will also switch to db index
|
// if db >= 0, will also switch to db index
|
||||||
func (b *browserService) getRedisClient(connName string, db int) (item connectionItem, err error) {
|
func (b *browserService) getRedisClient(connName string, db int) (item *connectionItem, err error) {
|
||||||
var ok bool
|
var ok bool
|
||||||
var client redis.UniversalClient
|
var client redis.UniversalClient
|
||||||
if item, ok = b.connMap[connName]; ok {
|
if item, ok = b.connMap[connName]; ok {
|
||||||
|
@ -275,7 +274,7 @@ func (b *browserService) getRedisClient(connName string, db int) (item connectio
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx, cancelFunc := context.WithCancel(b.ctx)
|
ctx, cancelFunc := context.WithCancel(b.ctx)
|
||||||
item = connectionItem{
|
item = &connectionItem{
|
||||||
client: client,
|
client: client,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancelFunc: cancelFunc,
|
cancelFunc: cancelFunc,
|
||||||
|
@ -289,14 +288,19 @@ func (b *browserService) getRedisClient(connName string, db int) (item connectio
|
||||||
b.connMap[connName] = item
|
b.connMap[connName] = item
|
||||||
}
|
}
|
||||||
|
|
||||||
if db >= 0 && item.db != db {
|
// BUG: go-redis might not be executing commands on the corresponding database
|
||||||
|
// requiring a database switch with each command
|
||||||
|
if db >= 0 /*&& item.db != db*/ {
|
||||||
var rdb *redis.Client
|
var rdb *redis.Client
|
||||||
if rdb, ok = client.(*redis.Client); ok && rdb != nil {
|
if rdb, ok = client.(*redis.Client); ok && rdb != nil {
|
||||||
if err = rdb.Do(item.ctx, "select", strconv.Itoa(db)).Err(); err != nil {
|
_, err = rdb.Pipelined(item.ctx, func(pipe redis.Pipeliner) error {
|
||||||
|
return pipe.Select(item.ctx, db).Err()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item.db = db
|
item.db = db
|
||||||
b.connMap[connName] = item
|
b.connMap[connName].db = db
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -358,7 +362,7 @@ func (b *browserService) parseDBItemInfo(info string) map[string]int {
|
||||||
|
|
||||||
// ServerInfo get server info
|
// ServerInfo get server info
|
||||||
func (b *browserService) ServerInfo(name string) (resp types.JSResp) {
|
func (b *browserService) ServerInfo(name string) (resp types.JSResp) {
|
||||||
item, err := b.getRedisClient(name, 0)
|
item, err := b.getRedisClient(name, -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
|
|
|
@ -154,8 +154,8 @@ const onDisconnect = () => {
|
||||||
const handleSelectDB = async (db) => {
|
const handleSelectDB = async (db) => {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
browserStore.closeDatabase(props.server, props.db)
|
|
||||||
browserStore.setKeyFilter(props.server, {})
|
browserStore.setKeyFilter(props.server, {})
|
||||||
|
browserStore.closeDatabase(props.server, props.db)
|
||||||
await browserStore.openDatabase(props.server, db)
|
await browserStore.openDatabase(props.server, db)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
await connectionStore.saveLastDB(props.server, db)
|
await connectionStore.saveLastDB(props.server, db)
|
||||||
|
@ -163,6 +163,7 @@ const handleSelectDB = async (db) => {
|
||||||
// browserTreeRef.value?.resetExpandKey(props.server, db)
|
// browserTreeRef.value?.resetExpandKey(props.server, db)
|
||||||
fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db)
|
fullyLoaded.value = await browserStore.loadMoreKeys(props.server, db)
|
||||||
browserTreeRef.value?.refreshTree()
|
browserTreeRef.value?.refreshTree()
|
||||||
|
tabStore.setSelectedKeys(props.server)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$message.error(e.message)
|
$message.error(e.message)
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -379,7 +379,7 @@ const renderPrefix = ({ option }) => {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (option.redisType == null || option.redisType === 'loading') {
|
if (isEmpty(option.redisType) || option.redisType === 'loading') {
|
||||||
browserStore.loadKeyType({
|
browserStore.loadKeyType({
|
||||||
server: props.server,
|
server: props.server,
|
||||||
db: option.db,
|
db: option.db,
|
||||||
|
|
|
@ -477,16 +477,22 @@ const useBrowserStore = defineStore('browser', {
|
||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async loadKeyType({ server, db, key, keyCode }) {
|
async loadKeyType({ server, db, key, keyCode }) {
|
||||||
|
const nodeMap = this._getNodeMap(server, db)
|
||||||
|
const node = nodeMap.get(`${ConnectionType.RedisValue}/${key}`)
|
||||||
|
if (node == null || !isEmpty(node.redisType)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const nodeMap = this._getNodeMap(server, db)
|
|
||||||
const node = nodeMap.get(`${ConnectionType.RedisValue}/${key}`)
|
|
||||||
if (node == null || node.redisType != null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
node.redisType = 'loading'
|
node.redisType = 'loading'
|
||||||
const { data } = await GetKeyType({ server, db, key: keyCode || key })
|
const { data, success } = await GetKeyType({ server, db, key: keyCode || key })
|
||||||
const { type } = data || {}
|
if (success) {
|
||||||
node.redisType = type
|
const { type } = data || {}
|
||||||
|
node.redisType = type
|
||||||
|
} else {
|
||||||
|
node.redisType = 'NONE'
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
node.redisType = 'NONE'
|
||||||
} finally {
|
} finally {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue