Skip to content

Conversation

@Artuomka
Copy link
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings December 23, 2025 16:25
@Artuomka Artuomka enabled auto-merge December 23, 2025 16:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements fixes and improvements for Redis backend functionality, introducing support for standalone Redis keys (keys without colons) as a new collection type and improving error handling for disabled Redis KEYS commands.

Key Changes:

  • Added STANDALONE_COLLECTION table type to handle Redis keys without prefixes
  • Implemented fallback from KEYS to SCAN command when KEYS is disabled
  • Removed maxTokens configuration from Amazon Bedrock AI provider

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 9 comments.

File Description
shared-code/src/data-access-layer/data-access-objects/data-access-object-redis.ts Major refactoring adding STANDALONE_COLLECTION support, new getKeysWithPattern helper method for KEYS command fallback, and whitespace normalization (spaces to tabs)
backend/src/interceptors/timeout.interceptor.ts Whitespace normalization only (spaces to tabs)
backend/src/entities/ai/amazon-bedrock/amazon-bedrock.ai.provider.ts Removed maxTokens configuration and reordered imports

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1953 to +1959
const tnlCachedObj = {
server: server,
client: client,
redis: redisClient,
};
LRUStorage.setTunnelCache(connectionCopy, tnlCachedObj);
resolve(tnlCachedObj.redis);
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name 'tnlCachedObj' uses an unclear abbreviation. Consider renaming to 'tunnelCachedObj' or 'cachedTunnel' for better readability and maintainability.

Suggested change
const tnlCachedObj = {
server: server,
client: client,
redis: redisClient,
};
LRUStorage.setTunnelCache(connectionCopy, tnlCachedObj);
resolve(tnlCachedObj.redis);
const tunnelCachedObj = {
server: server,
client: client,
redis: redisClient,
};
LRUStorage.setTunnelCache(connectionCopy, tunnelCachedObj);
resolve(tunnelCachedObj.redis);

Copilot uses AI. Check for mistakes.
Comment on lines +1939 to +1941
const cachedTnl = LRUStorage.getTunnelCache(connectionCopy);
if (cachedTnl?.redis && cachedTnl.server && cachedTnl.client) {
resolve(cachedTnl.redis);
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name 'cachedTnl' uses an unclear abbreviation. Consider renaming to 'cachedTunnel' for better readability.

Suggested change
const cachedTnl = LRUStorage.getTunnelCache(connectionCopy);
if (cachedTnl?.redis && cachedTnl.server && cachedTnl.client) {
resolve(cachedTnl.redis);
const cachedTunnel = LRUStorage.getTunnelCache(connectionCopy);
if (cachedTunnel?.redis && cachedTunnel.server && cachedTunnel.client) {
resolve(cachedTunnel.redis);

Copilot uses AI. Check for mistakes.
Comment on lines +753 to +780
try {
let value: unknown;
switch (keyType) {
case 'string':
value = await redisClient.get(key);
break;
case 'list':
value = `[list: ${await redisClient.lLen(key)} items]`;
break;
case 'set':
value = `[set: ${await redisClient.sCard(key)} members]`;
break;
case 'zset':
value = `[zset: ${await redisClient.zCard(key)} members]`;
break;
case 'hash':
value = `[hash: ${await redisClient.hLen(key)} fields]`;
break;
default:
value = `[${keyType}]`;
}

allRows.push({
key: key,
type: keyType,
value: value,
});
} catch (_error) {}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getStandaloneCollectionRows method processes all standalone keys in batches of 1000, which is good. However, for each key in the batch, it makes individual Redis calls (redisClient.get, redisClient.lLen, etc.) inside the loop after the pipeline execution. This could be optimized by using pipelines for these operations as well, especially when dealing with large numbers of keys. Consider batching these operations to reduce the number of round trips to Redis.

Copilot uses AI. Check for mistakes.

const command = new ConverseCommand({
modelId: this.modelId,
messages: conversation,
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the maxTokens configuration from inferenceConfig means the model will use its default token limit. This could lead to unexpectedly long responses or increased costs. If this change is intentional, consider documenting why the limit was removed. If not, the maxTokens parameter should be restored to control response length and costs.

Suggested change
messages: conversation,
messages: conversation,
inferenceConfig: {
maxTokens: 1024, // Limit response length to control cost and latency
},

Copilot uses AI. Check for mistakes.
Comment on lines +823 to +832
if (settings.ordering_field && settings.ordering) {
allRows.sort((a, b) => {
const aVal = a[settings.ordering_field];
const bVal = b[settings.ordering_field];
const modifier = settings.ordering === 'ASC' ? 1 : -1;

if (aVal < bVal) return -1 * modifier;
if (aVal > bVal) return 1 * modifier;
return 0;
});
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sorting logic doesn't handle null or undefined values properly. When comparing values with the less than or greater than operators, null or undefined values could cause unexpected sorting behavior. Consider adding explicit null/undefined checks in the comparison function to handle these edge cases consistently.

Copilot uses AI. Check for mistakes.
}

const totalRows = allRows.length;
console.log('🚀 ~ DataAccessObjectRedis ~ getStandaloneCollectionRows ~ allRows:', allRows);
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug console.log statement should be removed before merging to production. This line outputs potentially large datasets to the console which can impact performance and clutter logs.

Suggested change
console.log('🚀 ~ DataAccessObjectRedis ~ getStandaloneCollectionRows ~ allRows:', allRows);

Copilot uses AI. Check for mistakes.
Comment on lines +1998 to +1999
if (error?.message?.includes('KEYS command is disabled') || error?.message?.includes('please use SCAN')) {
return this.getAllKeysWithScan(redisClient, pattern);
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getKeysWithPattern method includes error handling that catches disabled KEYS commands and falls back to SCAN, which is good. However, the error detection logic uses optional chaining on error?.message which may not catch all error types. Consider checking if error is an Error instance first, or using a more robust error type check.

Copilot uses AI. Check for mistakes.

return result;
} catch (error) {
if (error?.message?.includes('KEYS command is disabled') || error?.message?.includes('please use SCAN')) {
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar error handling issue as in getKeysWithPattern. The optional chaining on error?.message may not work correctly for all error types. Consider verifying that error is an Error instance before accessing its message property.

Copilot uses AI. Check for mistakes.
result = Number(rowValue) <= Number(value);
break;
case FilterCriteriaEnum.empty:
result = rowValue === null || rowValue === undefined || rowValue === '';
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard always evaluates to false.

Suggested change
result = rowValue === null || rowValue === undefined || rowValue === '';
result = rowValue === null || rowValue === '';

Copilot uses AI. Check for mistakes.
@Artuomka Artuomka merged commit 6a3af80 into main Dec 23, 2025
25 checks passed
@Artuomka Artuomka deleted the backend_redis_fixes branch December 23, 2025 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants