Skip to content

Commit 1087d9f

Browse files
Copilothotlong
andcommitted
Fix code review issues: use Redis SCAN, improve error messages, clarify TTL
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 898ba80 commit 1087d9f

1 file changed

Lines changed: 25 additions & 14 deletions

File tree

NEXT_STEPS_ACTION_PLAN.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,14 @@ export class ObjectStackRuntimeProtocol {
164164
// Query Methods
165165
async findData(objectName: string, query?: any): Promise<{ value: any[]; count: number }> {
166166
if (!this.kernel.find) {
167-
throw new Error('Kernel does not support find operation');
167+
throw new Error('The kernel does not support the find operation');
168168
}
169169
return await this.kernel.find(objectName, query || {});
170170
}
171171

172172
async getData(objectName: string, id: string): Promise<any> {
173173
if (!this.kernel.get) {
174-
throw new Error('Kernel does not support get operation');
174+
throw new Error('The kernel does not support the get operation');
175175
}
176176
return await this.kernel.get(objectName, id);
177177
}
@@ -184,21 +184,21 @@ export class ObjectStackRuntimeProtocol {
184184
// Mutation Methods
185185
async createData(objectName: string, data: any): Promise<any> {
186186
if (!this.kernel.create) {
187-
throw new Error('Kernel does not support create operation');
187+
throw new Error('The kernel does not support the create operation');
188188
}
189189
return await this.kernel.create(objectName, data);
190190
}
191191

192192
async updateData(objectName: string, id: string, data: any): Promise<any> {
193193
if (!this.kernel.update) {
194-
throw new Error('Kernel does not support update operation');
194+
throw new Error('The kernel does not support the update operation');
195195
}
196196
return await this.kernel.update(objectName, id, data);
197197
}
198198

199199
async deleteData(objectName: string, id: string): Promise<boolean> {
200200
if (!this.kernel.delete) {
201-
throw new Error('Kernel does not support delete operation');
201+
throw new Error('The kernel does not support the delete operation');
202202
}
203203
return await this.kernel.delete(objectName, id);
204204
}
@@ -338,7 +338,7 @@ import type Redis from 'ioredis';
338338
export interface RedisPermissionStorageConfig {
339339
redis: Redis;
340340
keyPrefix?: string;
341-
ttl?: number; // Time to live in seconds
341+
ttl?: number; // Time to live in seconds (sliding expiration - refreshed on each access)
342342
}
343343

344344
export class RedisPermissionStorage {
@@ -369,20 +369,31 @@ export class RedisPermissionStorage {
369369
await this.redis.del(key);
370370
} else {
371371
// Delete all permissions for role
372+
// Using SCAN instead of KEYS for production safety (non-blocking)
372373
const pattern = `${this.keyPrefix}${role}:*`;
373-
const keys = await this.redis.keys(pattern);
374-
if (keys.length > 0) {
375-
await this.redis.del(...keys);
376-
}
374+
await this.scanAndDelete(pattern);
377375
}
378376
}
379377

380378
async clear(): Promise<void> {
379+
// Using SCAN instead of KEYS for production safety (non-blocking)
381380
const pattern = `${this.keyPrefix}*`;
382-
const keys = await this.redis.keys(pattern);
383-
if (keys.length > 0) {
384-
await this.redis.del(...keys);
385-
}
381+
await this.scanAndDelete(pattern);
382+
}
383+
384+
/**
385+
* Safely delete keys matching pattern using SCAN (non-blocking)
386+
* @private
387+
*/
388+
private async scanAndDelete(pattern: string): Promise<void> {
389+
let cursor = '0';
390+
do {
391+
const [newCursor, keys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
392+
cursor = newCursor;
393+
if (keys.length > 0) {
394+
await this.redis.del(...keys);
395+
}
396+
} while (cursor !== '0');
386397
}
387398
}
388399
```

0 commit comments

Comments
 (0)