Skip to content

✨AI Column: Create cache mechanism#31569

Merged
Raushen merged 19 commits intoDevExpress:25_2from
Raushen:AI-Column-Cache
Nov 5, 2025
Merged

✨AI Column: Create cache mechanism#31569
Raushen merged 19 commits intoDevExpress:25_2from
Raushen:AI-Column-Cache

Conversation

@Raushen
Copy link
Contributor

@Raushen Raushen commented Nov 3, 2025

No description provided.

@Raushen Raushen self-assigned this Nov 3, 2025
@Raushen Raushen requested a review from a team as a code owner November 3, 2025 21:16
Copilot AI review requested due to automatic review settings November 3, 2025 21:16
@Raushen Raushen added the 25_2 label Nov 3, 2025
Copy link
Contributor

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 caching functionality for AI column data in the DevExtreme grid. The changes transform stub methods in the AIColumnCacheController into a working in-memory cache implementation using nested Map structures.

Key changes:

  • Implemented cache storage using Map<string, Map<PropertyKey, string>> to store AI column responses
  • Added cache persistence after successful AI column requests
  • Connected cache operations to the controller methods for retrieval and clearing

Reviewed Changes

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

File Description
m_ai_column_cache_controller.ts Implemented in-memory cache with Map-based storage and full CRUD operations
m_ai_column_integration_controller.ts Added cache persistence after receiving AI responses and exposed cache retrieval/clearing methods
m_ai_column_controller.ts Updated parameter type from any to unknown and delegated cache operations to integration controller
Comments suppressed due to low confidence (2)

packages/devextreme/js/__internal/grids/grid_core/ai_column/m_ai_column_integration_controller.ts:200

  • The dispose method doesn't dispose of the aiColumnCacheController instance. Since aiColumnCacheController has its own dispose method that clears the cache, it should be called here to prevent memory leaks: this.aiColumnCacheController.dispose();
  public dispose(): void {
    super.dispose();
    Object.keys(this.aborts).forEach((columnName) => this.abortRequest(columnName));
  }

packages/devextreme/js/__internal/grids/grid_core/ai_column/m_ai_column_controller.ts:110

  • The dispose method doesn't dispose of the aiColumnIntegrationController instance. This should call this.aiColumnIntegrationController.dispose(); to properly clean up resources and prevent memory leaks.
  public dispose(): void {
    this.dataController.changed.remove(this.dataChangedHandler);
  }

Copilot AI review requested due to automatic review settings November 4, 2025 10:15
Copy link
Contributor

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings November 4, 2025 15:38
Copy link
Contributor

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings November 4, 2025 18:39
Copy link
Contributor

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

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

Copilot AI review requested due to automatic review settings November 4, 2025 19:18
Copy link
Contributor

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

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings November 5, 2025 09:27
Copy link
Contributor

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

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

Copilot AI review requested due to automatic review settings November 5, 2025 11:28
Copy link
Contributor

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

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

Comment on lines +76 to +80
let cachedResponse: Record<PropertyKey, string> = {};
if (args.useCache) {
const keys = data.map((item) => item[keyField] as PropertyKey);
cachedResponse = this.aiColumnCacheController.getCachedResponse(columnName, keys);
}
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

[nitpick] The variable declaration and initialization could be simplified. Consider declaring cachedResponse inside the if block or using a more explicit initialization pattern. The current approach initializes an empty object that gets immediately reassigned when args.useCache is true.

Suggested change
let cachedResponse: Record<PropertyKey, string> = {};
if (args.useCache) {
const keys = data.map((item) => item[keyField] as PropertyKey);
cachedResponse = this.aiColumnCacheController.getCachedResponse(columnName, keys);
}
const cachedResponse: Record<PropertyKey, string> = args.useCache
? this.aiColumnCacheController.getCachedResponse(
columnName,
data.map((item) => item[keyField] as PropertyKey),
)
: {};

Copilot uses AI. Check for mistakes.
this.cache[columnName] = columnCache;
}
Object.entries(data).forEach(([key, value]) => {
if (columnCache && value !== '') {
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

Inconsistent handling of empty string values. In getCachedResponse, empty strings are filtered out during retrieval (line 16), but in setCachedResponse, they're prevented from being stored. This dual filtering is redundant and could mask issues. Consider standardizing to handle empty strings in one location only.

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +152
super.dispose();
if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
}
if (this.dataChangedHandler) {
this.dataController.changed.remove(this.dataChangedHandler);
}
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

The super.dispose() call should typically come after cleaning up the component's own resources, not before. This ensures that if the parent's dispose method has any dependencies on the current state, they're still available. Consider moving super.dispose() to the end of the method.

Suggested change
super.dispose();
if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
}
if (this.dataChangedHandler) {
this.dataController.changed.remove(this.dataChangedHandler);
}
if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
}
if (this.dataChangedHandler) {
this.dataController.changed.remove(this.dataChangedHandler);
}
super.dispose();

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +161
super.dispose();

if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
}
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

Similar to AIColumnController, the super.dispose() call should typically come after cleaning up component-specific resources. Consider moving super.dispose() to the end of the dispose method.

Suggested change
super.dispose();
if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
}
if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
}
super.dispose();

Copilot uses AI. Check for mistakes.
super.dispose();

if (this.aiColumnOptionChangedHandler) {
this.columnsController.aiColumnOptionChanged.remove(this.aiColumnOptionChangedHandler);
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not necessary to remove this method from the callback list. This is done at the base level.

@Raushen Raushen merged commit 05c6fb4 into DevExpress:25_2 Nov 5, 2025
114 of 116 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants