fix(#337): Replace blocking KEYS command with SCAN in Valkey client
- Use SCAN with cursor for non-blocking iteration - Prevents Redis DoS under high key counts - Same API, safer implementation Refs #337 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -113,7 +113,7 @@ export class ValkeyClient {
|
||||
|
||||
async listTasks(): Promise<TaskState[]> {
|
||||
const pattern = "orchestrator:task:*";
|
||||
const keys = await this.client.keys(pattern);
|
||||
const keys = await this.scanKeys(pattern);
|
||||
|
||||
const tasks: TaskState[] = [];
|
||||
for (const key of keys) {
|
||||
@@ -184,7 +184,7 @@ export class ValkeyClient {
|
||||
|
||||
async listAgents(): Promise<AgentState[]> {
|
||||
const pattern = "orchestrator:agent:*";
|
||||
const keys = await this.client.keys(pattern);
|
||||
const keys = await this.scanKeys(pattern);
|
||||
|
||||
const agents: AgentState[] = [];
|
||||
for (const key of keys) {
|
||||
@@ -238,6 +238,23 @@ export class ValkeyClient {
|
||||
* Private helper methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Scan keys using SCAN command (non-blocking alternative to KEYS)
|
||||
* Uses cursor-based iteration to avoid blocking Redis
|
||||
*/
|
||||
private async scanKeys(pattern: string): Promise<string[]> {
|
||||
const keys: string[] = [];
|
||||
let cursor = "0";
|
||||
|
||||
do {
|
||||
const [nextCursor, batch] = await this.client.scan(cursor, "MATCH", pattern, "COUNT", 100);
|
||||
cursor = nextCursor;
|
||||
keys.push(...batch);
|
||||
} while (cursor !== "0");
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
private getTaskKey(taskId: string): string {
|
||||
return `orchestrator:task:${taskId}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user