mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-03 04:59:46 +08:00
🐛 fix(redis-viewer): 修复大数据量场景 Key 加载不完整问题
- 后端 ScanKeys 改为按目标数量多轮聚合扫描,不再只依赖单轮返回结果 - 新增扫描目标数/步长/轮次上限,避免扫描过少或无限循环 - 前端首屏加载、搜索、刷新统一按较大批次请求,避免回退到几百条 - 加载更多改为按固定批次继续拉取并保持去重合并 - refs #129
This commit is contained in:
@@ -14,6 +14,8 @@ const REDIS_TREE_KEY_TYPE_WIDTH = 92;
|
||||
const REDIS_TREE_KEY_TYPE_WIDTH_NARROW = 84;
|
||||
const REDIS_TREE_KEY_TTL_WIDTH = 92;
|
||||
const REDIS_TREE_HIDE_TTL_THRESHOLD = 460;
|
||||
const REDIS_KEY_INITIAL_LOAD_COUNT = 2000;
|
||||
const REDIS_KEY_LOAD_MORE_COUNT = 2000;
|
||||
|
||||
interface RedisViewerProps {
|
||||
connectionId: string;
|
||||
@@ -462,27 +464,34 @@ const RedisViewer: React.FC<RedisViewerProps> = ({ connectionId, redisDB }) => {
|
||||
};
|
||||
}, [connection, redisDB]);
|
||||
|
||||
const loadKeys = useCallback(async (pattern: string = '*', fromCursor: number = 0, append: boolean = false) => {
|
||||
const loadKeys = useCallback(async (
|
||||
pattern: string = '*',
|
||||
fromCursor: number = 0,
|
||||
append: boolean = false,
|
||||
targetCount: number = REDIS_KEY_INITIAL_LOAD_COUNT
|
||||
) => {
|
||||
const config = getConfig();
|
||||
if (!config) return;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await (window as any).go.app.App.RedisScanKeys(config, pattern, fromCursor, 100);
|
||||
const res = await (window as any).go.app.App.RedisScanKeys(config, pattern, fromCursor, targetCount);
|
||||
if (res.success) {
|
||||
const result = res.data;
|
||||
const scannedKeys = Array.isArray(result?.keys) ? result.keys : [];
|
||||
const nextCursor = Number(result?.cursor || 0);
|
||||
if (append) {
|
||||
setKeys(prev => {
|
||||
const keyMap = new Map<string, RedisKeyInfo>();
|
||||
prev.forEach(item => keyMap.set(item.key, item));
|
||||
result.keys.forEach((item: RedisKeyInfo) => keyMap.set(item.key, item));
|
||||
scannedKeys.forEach((item: RedisKeyInfo) => keyMap.set(item.key, item));
|
||||
return Array.from(keyMap.values());
|
||||
});
|
||||
} else {
|
||||
setKeys(result.keys);
|
||||
setKeys(scannedKeys);
|
||||
}
|
||||
setCursor(result.cursor);
|
||||
setHasMore(result.cursor !== 0);
|
||||
setCursor(nextCursor);
|
||||
setHasMore(nextCursor !== 0);
|
||||
} else {
|
||||
message.error('加载 Key 失败: ' + res.message);
|
||||
}
|
||||
@@ -494,23 +503,26 @@ const RedisViewer: React.FC<RedisViewerProps> = ({ connectionId, redisDB }) => {
|
||||
}, [getConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
loadKeys(searchPattern, 0, false);
|
||||
loadKeys(searchPattern, 0, false, REDIS_KEY_INITIAL_LOAD_COUNT);
|
||||
}, [redisDB]);
|
||||
|
||||
const handleSearch = (value: string) => {
|
||||
const pattern = value.trim() || '*';
|
||||
setSearchPattern(pattern);
|
||||
setCursor(0);
|
||||
loadKeys(pattern, 0, false);
|
||||
loadKeys(pattern, 0, false, REDIS_KEY_INITIAL_LOAD_COUNT);
|
||||
};
|
||||
|
||||
const handleLoadMore = () => {
|
||||
loadKeys(searchPattern, cursor, true);
|
||||
if (!hasMore || loading) {
|
||||
return;
|
||||
}
|
||||
loadKeys(searchPattern, cursor, true, REDIS_KEY_LOAD_MORE_COUNT);
|
||||
};
|
||||
|
||||
const handleRefresh = () => {
|
||||
setCursor(0);
|
||||
loadKeys(searchPattern, 0, false);
|
||||
loadKeys(searchPattern, 0, false, REDIS_KEY_INITIAL_LOAD_COUNT);
|
||||
};
|
||||
|
||||
const loadKeyValue = async (key: string) => {
|
||||
@@ -1777,7 +1789,7 @@ const RedisViewer: React.FC<RedisViewerProps> = ({ connectionId, redisDB }) => {
|
||||
</Spin>
|
||||
{hasMore && (
|
||||
<div style={{ padding: 8, textAlign: 'center' }}>
|
||||
<Button onClick={handleLoadMore} loading={loading}>加载更多</Button>
|
||||
<Button onClick={handleLoadMore} loading={loading} disabled={!hasMore || loading}>加载更多</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user