Files
calypso/docs/DATASET-CACHE-FIX.md
2025-12-25 20:02:59 +00:00

3.3 KiB
Raw Permalink Blame History

Dataset Cache Invalidation Fix

Issue

Datasets were not automatically refreshing in the UI after create/delete operations:

  • Creating a dataset: Dataset created in OS but not shown in UI until manual refresh
  • Deleting a dataset: Dataset deleted from OS but still showing in UI until manual refresh

Root Cause

The React Query cache invalidation logic was overly complex with:

  1. Multiple invalidation strategies (removeQueries, invalidateQueries, refetchQueries)
  2. Manual refresh triggers with complex state management
  3. Race conditions between cache removal and refetch
  4. Delays and multiple refetch attempts

This created inconsistent behavior where the cache wasn't properly updated.

Solution

Simplified the cache invalidation to use React Query's built-in mechanism:

Before (Complex)

\\ ypescript onSuccess: async (_, variables) => { // Multiple cache operations queryClient.removeQueries(...) await queryClient.invalidateQueries(...) await new Promise(resolve => setTimeout(resolve, 500)) await queryClient.refetchQueries(...) setDatasetRefreshTrigger(...) // Manual trigger // More refetch attempts... } \\

After (Simple)

\\ ypescript onSuccess: async (_, variables) => { setExpandedPools(prev => new Set(prev).add(variables.poolId)) await queryClient.invalidateQueries({ queryKey: ['storage', 'zfs', 'pools', variables.poolId, 'datasets'] }) await queryClient.refetchQueries({ queryKey: ['storage', 'zfs', 'pools', variables.poolId, 'datasets'] }) } \\

Changes Made

1. Simplified createDataset Mutation

File: rontend/src/pages/Storage.tsx (line 256-267)

  • Removed complex cache removal logic
  • Removed refresh trigger state updates
  • Removed delays
  • Simplified to: invalidate → refetch

2. Simplified deleteDataset Mutation

File: rontend/src/pages/Storage.tsx (line 274-285)

  • Same simplification as createDataset
  • Removed 62 lines of complex cache logic
  • Reduced from ~60 lines to 8 lines

3. Removed Unused State

  • Removed datasetRefreshTrigger state variable (line 175)
  • Removed efreshTrigger prop from DatasetRows component (line 633)

Technical Details

Why This Works Better

  1. invalidateQueries: Marks the query as stale
  2. refetchQueries: Immediately fetches fresh data from API
  3. No race conditions: Operations happen in order
  4. No manual triggers: React Query handles cache automatically
  5. Consistent behavior: Same logic for create and delete

React Query Best Practices

  • Use invalidateQueries to mark data as stale
  • Use efetchQueries to immediately get fresh data
  • Let React Query manage the cache lifecycle
  • Avoid manual emoveQueries unless necessary
  • Don't use setTimeout for synchronization

Testing

After the fix:

  1. Create dataset → Immediately appears in UI
  2. Delete dataset → Immediately removed from UI
  3. No manual refresh needed
  4. Build successful (9.99s)
  5. No TypeScript errors

Files Modified

  • rontend/src/pages/Storage.tsx
    • Lines reduced: ~120 lines → ~60 lines in mutation logic
    • Complexity reduced: High → Low
    • Maintainability: Improved

Backup

Original file backed up to: rontend/src/pages/Storage.tsx.backup


Date: 2025-12-25 Status: Fixed and Tested Build: Successful Impact: Dataset UI now updates immediately on create/delete