-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ignore not relevant tasks/projects/jobs responses #8653
Conversation
WalkthroughThe changes across the CVAT codebase focus on enhancing the handling of asynchronous data fetching for jobs, projects, and tasks by introducing a Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (13)
cvat-ui/src/containers/tasks-page/tasks-list.tsx (1)
Line range hint
1-31
: Well-structured architectural changesThe refactoring improves the component architecture by:
- Following the container/presentational pattern more strictly
- Moving task fetching responsibility out of the component
- Reducing component complexity
This aligns well with React/Redux best practices and makes the code more maintainable.
cvat-ui/src/containers/tasks-page/task-item.tsx (1)
9-9
: LGTM! Clean up of imports aligns with architectural changes.The removal of unused imports reflects the architectural change to centralize task fetching logic elsewhere, improving the separation of concerns.
This change follows good practices by:
- Removing unnecessary dependencies
- Moving data fetching responsibility away from individual components
Also applies to: 11-11
cvat-ui/src/reducers/jobs-reducer.ts (1)
10-10
: Consider enhancing timestamp handlingTwo suggestions to improve the implementation:
- Consider centralizing the timestamp comparison logic into a reusable utility
- Add type safety for the timestamp
Example implementation:
// types.ts export type FetchingTimestamp = number & { readonly __brand: unique symbol }; export const createFetchingTimestamp = (): FetchingTimestamp => Date.now() as FetchingTimestamp; // utils.ts export const isStaleRequest = ( stateTimestamp: FetchingTimestamp, requestTimestamp: FetchingTimestamp, ): boolean => stateTimestamp > requestTimestamp;Also applies to: 31-31
cvat-ui/src/actions/jobs-actions.ts (2)
78-83
: LGTM: Well-implemented request relevance checking.The timestamp-based validation mechanism is properly implemented. Consider adding debug logging when requests are determined to be irrelevant to aid in troubleshooting.
const isRequestRelevant = (): boolean => { - getState().jobs.fetchingTimestamp === requestedOn + const relevant = getState().jobs.fetchingTimestamp === requestedOn; + if (!relevant) { + console.debug(`Skipping irrelevant jobs response (requested: ${requestedOn}, current: ${getState().jobs.fetchingTimestamp})`); + } + return relevant; }
88-97
: Consider using high-resolution timestamps for better precision.While the current implementation using
Date.now()
works well for most cases, it could potentially lead to race conditions if multiple requests are made within the same millisecond. Consider usingperformance.now()
for higher precision timestamps.- const requestedOn = Date.now(); + const requestedOn = Math.floor(performance.now());cvat-ui/src/reducers/tasks-reducer.ts (2)
47-47
: Consider adding type safety for the action payload.While the
fetchingTimestamp
update is correct, the action payload structure lacks type safety. Consider defining an interface for the payload to ensure type checking at compile time.interface GetTasksPayload { fetchingTimestamp: number; updateQuery: boolean; query?: { page?: number; id?: number | null; search?: string | null; filter?: string | null; sort?: string | null; projectId?: number | null; }; } // Then use it in the action type definition case TasksActionTypes.GET_TASKS: { const payload = action.payload as GetTasksPayload; return { ...state, fetchingTimestamp: payload.fetchingTimestamp, // ... rest of the state updates }; }
15-15
: Add documentation for the timestamp-based relevance checking.The
fetchingTimestamp
implementation would benefit from documentation explaining:
- The purpose of tracking request timestamps
- How it's used to determine response relevance
- Examples of scenarios where responses might be ignored
This will help future maintainers understand the reasoning behind this implementation.
Add comments like:
// Tracks when tasks are fetched to handle race conditions // If a response arrives with an older timestamp than a newer request, // it will be ignored to prevent stale data updates fetchingTimestamp: Date.now(),Also applies to: 47-47
cvat-ui/src/reducers/projects-reducer.ts (2)
15-15
: LGTM: Good addition of timestamp tracking.The
fetchingTimestamp
addition is a good approach for tracking request relevance. This will help prevent race conditions where older responses could override newer data.Consider documenting the timestamp comparison logic in a central place (e.g., README or API docs) to ensure consistent implementation across all async operations.
Line range hint
163-227
: Consider refactoring preview state management for better maintainability.The preview-related reducers follow a similar pattern that could be extracted into a reusable utility function to reduce code duplication and improve maintainability.
Consider refactoring the preview state management like this:
const createPreviewReducer = (state: ProjectsState, action: AnyAction, status: { fetching: boolean; initialized: boolean; preview?: string; }) => { const { projectID } = action.payload; const { previews } = state; return { ...state, previews: { ...previews, [projectID]: { ...previews[projectID], ...status, }, }, }; }; // Then use it in the reducer: case ProjectsActionTypes.GET_PROJECT_PREVIEW: return createPreviewReducer(state, action, { preview: '', fetching: true, initialized: false, }); case ProjectsActionTypes.GET_PROJECT_PREVIEW_SUCCESS: return createPreviewReducer(state, action, { preview: action.payload.preview, fetching: false, initialized: true, });cvat-ui/src/actions/projects-actions.ts (1)
114-123
: Consider consolidating relevance checks.The task fetching logic could potentially execute for an irrelevant request if the relevance changes between the outer check and the task fetching dispatch. Consider moving the project ID check inside the relevance check.
if (isRequestRelevant()) { const array = Array.from(result); dispatch(projectActions.getProjectsSuccess(array, result.count)); - // Appropriate tasks fetching process needs with retrieving only a single project - if (Object.keys(filteredQuery).includes('id') && typeof filteredQuery.id === 'number') { - dispatch(getProjectTasksAsync({ - ...tasksQuery, - projectId: filteredQuery.id, - })); - } + // Fetch tasks only if still relevant and dealing with a single project + if (isRequestRelevant() && + Object.keys(filteredQuery).includes('id') && + typeof filteredQuery.id === 'number') { + dispatch(getProjectTasksAsync({ + ...tasksQuery, + projectId: filteredQuery.id, + })); + } }cvat-ui/src/actions/tasks-actions.ts (1)
73-96
: Consider improvements for better maintainability.While the implementation is solid, consider these improvements:
- Extract
isRequestRelevant
to a shared utility function as this pattern might be reused- Add debug logging for skipped responses to aid troubleshooting
- Consider more granular error type checking before skipping error responses
Example implementation:
// utils/request-helpers.ts export const createRelevanceChecker = (getState: () => any, stateKey: string) => { return (requestedOn: number): boolean => getState()[stateKey].fetchingTimestamp === requestedOn; }; // In your action const isRequestRelevant = createRelevanceChecker(getState, 'tasks');cvat-ui/src/reducers/index.ts (2)
41-41
: Add JSDoc comments to document the purpose of fetchingTimestamp.The addition of
fetchingTimestamp
to track fetch request timing is good. Consider adding JSDoc comments to clarify its purpose and expected format.+ /** Unix timestamp of the last fetch request. Used to handle out-of-order responses. */ fetchingTimestamp: number;
Also applies to: 79-79, 95-95
41-41
: Consider using a more specific type for timestamp.While
number
works, consider using a more specific type to ensure consistency in timestamp handling.- fetchingTimestamp: number; + fetchingTimestamp: EpochTimeStamp;This provides better type safety and self-documentation, as
EpochTimeStamp
specifically represents Unix timestamps in milliseconds.Also applies to: 79-79, 95-95
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (9)
cvat-ui/src/actions/jobs-actions.ts
(2 hunks)cvat-ui/src/actions/projects-actions.ts
(3 hunks)cvat-ui/src/actions/tasks-actions.ts
(2 hunks)cvat-ui/src/containers/tasks-page/task-item.tsx
(1 hunks)cvat-ui/src/containers/tasks-page/tasks-list.tsx
(2 hunks)cvat-ui/src/reducers/index.ts
(3 hunks)cvat-ui/src/reducers/jobs-reducer.ts
(2 hunks)cvat-ui/src/reducers/projects-reducer.ts
(2 hunks)cvat-ui/src/reducers/tasks-reducer.ts
(2 hunks)
🔇 Additional comments (15)
cvat-ui/src/containers/tasks-page/tasks-list.tsx (4)
2-2
: LGTM: Copyright update
Copyright notice properly updated to include current year and CVAT.ai Corporation.
8-8
: LGTM: Import optimization
Imports have been appropriately simplified to match the component's reduced responsibilities after removing task fetching logic.
31-31
: LGTM: Simplified Redux connection
Connect statement properly simplified to only include mapStateToProps, following Redux best practices for presentational components.
21-21
: LGTM: Simplified component props
Component correctly simplified to only handle state props, improving separation of concerns.
Let's verify how task fetching is now handled:
✅ Verification successful
Based on the search results, I can now generate the final response:
Task fetching is properly handled in tasks-page component
The task fetching logic has been moved to the tasks-page component which dispatches getTasksAsync
action. This is a better separation of concerns:
- Task fetching is implemented in
cvat-core/src/server-proxy.ts
viagetTasks
function - Action creators in
actions/tasks-actions.ts
handle the Redux workflow tasks-page.tsx
component manages when to fetch tasks throughuseEffect
and user interactions
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find where task fetching is now implemented
# Expected: Find new implementation in actions or effects
# Search for task fetching related code
rg -t typescript -t javascript "getTasks.*" --glob "!*.test.*" -A 5
Length of output: 104
Script:
#!/bin/bash
# Let's try different search patterns and commands to find task fetching logic
# Search for task fetching related code with ripgrep
rg "fetchTasks|getTask" --type ts --type js -A 5
# Also search for any task-related actions or effects
rg "tasks.*action|tasks.*effect" --type ts --type js -A 5
# Look for task-related imports and API calls
rg "import.*task|\/tasks" --type ts --type js -A 5
Length of output: 20597
cvat-ui/src/containers/tasks-page/task-item.tsx (2)
Line range hint 14-19
: LGTM! Well-structured component with clear responsibilities.
The remaining code maintains a clean structure with:
- Well-defined TypeScript interfaces
- Proper error handling for deleted tasks
- Clear separation of concerns in state and dispatch mappings
Also applies to: 25-44, 59-67
Line range hint 20-24
: Verify the impact of removing getTasks.
The removal of the getTasks
method from DispatchToProps
looks correct, but let's verify that task fetching is properly handled elsewhere in the codebase.
Let's check where task fetching is now handled:
Also applies to: 45-58
✅ Verification successful
Task fetching is properly handled in tasks-page component
The removal of getTasks
from task-item.tsx
is correct as the task fetching responsibility is properly handled in the main tasks page component. Specifically:
- Task fetching is managed by
getTasksAsync
action incvat-ui/src/components/tasks-page/tasks-page.tsx
- The tasks list data flow is properly structured:
TasksPageComponent
handles fetching viagetTasksAsync
TasksListContainer
receives tasks from Redux stateTaskItemComponent
only handles individual task updates
The code removal is safe as it follows proper separation of concerns, where task fetching is centralized in the parent component rather than individual task items.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find where task fetching is now handled after its removal from task-item.tsx
# Look for getTasksAsync usage
echo "Searching for getTasksAsync usage:"
rg "getTasksAsync" --type ts --type tsx
# Look for task fetching related components
echo -e "\nSearching for potential task list components:"
rg "TasksList|TasksPage" --type ts --type tsx
# Look for related Redux actions
echo -e "\nSearching for task-related Redux actions:"
rg "tasks-actions" --type ts --type tsx
Length of output: 496
Script:
#!/bin/bash
# Let's try without explicit file type flags since tsx might not be recognized
# Look for getTasksAsync usage
echo "Searching for getTasksAsync usage:"
rg "getTasksAsync"
# Look for task fetching related components
echo -e "\nSearching for potential task list components:"
rg "TasksList|TasksPage"
# Look for task-related Redux actions and state
echo -e "\nSearching for task-related Redux actions and state:"
rg "tasks/actions|tasksSlice|fetchTasks"
# Look specifically in the tasks-page directory
echo -e "\nSearching in tasks-page directory:"
fd . cvat-ui/src/containers/tasks-page/ -t f -x cat {}
Length of output: 6038
cvat-ui/src/reducers/jobs-reducer.ts (2)
10-10
: LGTM: Timestamp initialization is correct
The fetchingTimestamp
is properly initialized using Date.now()
in the default state, which will help track request relevance.
Line range hint 31-37
: Verify race condition handling in success/failure cases
While the timestamp handling in the GET_JOBS action is correct, we should verify that the success/failure cases properly handle race conditions when multiple requests are in flight.
Let's check if there's proper request relevance checking in the actions file:
✅ Verification successful
Race conditions are properly handled
The code correctly handles race conditions for multiple in-flight requests:
- A timestamp is generated and stored when a request is initiated
- The
isRequestRelevant()
helper compares the stored timestamp with the original request time - Both success and failure handlers verify request relevance before dispatching actions
- Only the most recent request's response will be processed, older responses are discarded
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if GET_JOBS_SUCCESS and GET_JOBS_FAILED actions verify request relevance
# Expected: Find timestamp comparison logic in the actions file
# Search for timestamp comparison in jobs actions
rg -A 5 "GET_JOBS_SUCCESS|GET_JOBS_FAILED" "cvat-ui/src/actions/jobs-actions.ts"
# Search for isRequestRelevant helper
rg "isRequestRelevant" "cvat-ui/src/actions/"
Length of output: 1569
Script:
#!/bin/bash
# Let's check the implementation of isRequestRelevant in jobs-actions.ts
rg -B 10 -A 10 "isRequestRelevant = \(\)" "cvat-ui/src/actions/jobs-actions.ts"
Length of output: 789
Script:
#!/bin/bash
# Let's verify how the isRequestRelevant is used in success/failure handlers
rg -B 20 -A 10 "if \(isRequestRelevant\(\)\)" "cvat-ui/src/actions/jobs-actions.ts"
Length of output: 1281
cvat-ui/src/actions/jobs-actions.ts (1)
37-39
: LGTM: Action creator properly updated with timestamp tracking.
The addition of fetchingTimestamp
parameter to the getJobs
action creator is well-implemented and aligns with the PR's objective of handling irrelevant responses.
cvat-ui/src/reducers/tasks-reducer.ts (1)
15-15
: LGTM: Timestamp initialization looks good.
The fetchingTimestamp
is correctly initialized using Date.now()
in the default state, which will help track the relevance of task responses.
cvat-ui/src/reducers/projects-reducer.ts (1)
Line range hint 63-67
: LGTM: Proper state management for project fetching.
The implementation correctly handles the loading state and data reset. The timestamp from the action payload is properly stored for tracking request relevance.
Let's verify the timestamp handling in the corresponding action creator:
✅ Verification successful
Timestamp handling in project fetching is correctly implemented
The implementation shows proper timestamp handling:
- Action creator sets
requestedOn
timestamp usingDate.now()
- Timestamp is used to track request relevance via
isRequestRelevant()
check - Reducer correctly updates state with the timestamp from action payload
- State reset (initialized, count, current) prevents stale data display
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the fetchingTimestamp is properly set in the action creator
# and consistently used across the codebase
# Check for the action creator implementation
rg -A 5 "GET_PROJECTS.*payload.*fetchingTimestamp" cvat-ui/src/actions/
# Verify similar timestamp handling in related files
rg -l "fetchingTimestamp" cvat-ui/src/reducers/
Length of output: 267
Script:
#!/bin/bash
# Let's check the action creators and related code more thoroughly
# Search for GET_PROJECTS action type definition and usage
rg -A 10 "GET_PROJECTS.*=.*" cvat-ui/src/actions/
# Check the actual implementation of projects fetching
rg -A 10 "function.*getProjects" cvat-ui/src/actions/
# Look for timestamp usage in reducers
rg -B 2 -A 5 "fetchingTimestamp" cvat-ui/src/reducers/projects-reducer.ts
Length of output: 2679
cvat-ui/src/actions/projects-actions.ts (2)
89-94
: LGTM! Effective race condition prevention.
The timestamp-based request validation effectively prevents race conditions by tracking the relevance of each request.
36-36
: Verify all getProjects action dispatches.
The action creator now requires a timestamp parameter, which is a breaking change. Let's verify all dispatch calls are updated.
✅ Verification successful
Let me search for any other potential usages of getProjects
that might not be direct dispatches.
Let me check the implementation of getProjectsAsync
to understand how the timestamp is being used and verify if all calls are properly handled.
Based on the comprehensive analysis of the codebase, I can now provide the final response:
Breaking change is properly handled in all usages
The getProjects
action creator's timestamp parameter is correctly managed:
- The
getProjectsAsync
thunk function internally generates the timestamp usingDate.now()
- All calls to
getProjects
are made throughgetProjectsAsync
- No direct usage of
getProjects
action creator exists outside ofgetProjectsAsync
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for direct getProjects action dispatches that might need updating
rg "dispatch\(.*getProjects\([^)]*\)" --type ts
Length of output: 148
Script:
#!/bin/bash
# Search for any usage of getProjects action
rg "getProjects" --type ts -A 2
Length of output: 5848
Script:
#!/bin/bash
# Get the implementation of getProjectsAsync
rg "export function getProjectsAsync" -A 30 --type ts
Length of output: 2409
cvat-ui/src/actions/tasks-actions.ts (2)
Line range hint 35-43
: LGTM: Clean implementation of timestamp tracking.
The addition of fetchingTimestamp
to the action payload is a good approach for tracking request relevance. This change enables the state to maintain the timestamp of the most recent request.
73-79
: LGTM: Effective request relevance tracking implementation.
The timestamp-based relevance checking effectively prevents race conditions from out-of-order responses. Let's verify the implementation across the codebase.
✅ Verification successful
Request relevance checking is consistently implemented across async actions
The implementation is correctly synchronized across tasks, projects, and jobs actions:
- All three modules use the same timestamp-based relevance checking pattern
- Each has proper reducer handling of
fetchingTimestamp
- Relevance checks are consistently applied before dispatching success/failure actions
- The pattern effectively prevents race conditions from out-of-order responses
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify consistent implementation of request relevance checking across related files
# Check for similar patterns in other async action files
echo "Checking for consistent implementation in other action files..."
rg -l "isRequestRelevant|fetchingTimestamp" "cvat-ui/src/actions/"
# Verify reducer handling of fetchingTimestamp
echo "Verifying reducer handling..."
rg "fetchingTimestamp" "cvat-ui/src/reducers/"
Length of output: 1157
Script:
#!/bin/bash
# Let's verify the implementation consistency across these files
# Check tasks implementation
echo "=== Tasks Implementation ==="
rg -A 10 "isRequestRelevant" "cvat-ui/src/actions/tasks-actions.ts"
# Check projects implementation
echo "=== Projects Implementation ==="
rg -A 10 "isRequestRelevant" "cvat-ui/src/actions/projects-actions.ts"
# Check jobs implementation
echo "=== Jobs Implementation ==="
rg -A 10 "isRequestRelevant" "cvat-ui/src/actions/jobs-actions.ts"
Length of output: 3202
Motivation and context
How has this been tested?
Checklist
develop
branch(cvat-canvas,
cvat-core,
cvat-data and
cvat-ui)
License
Feel free to contact the maintainers if that's a concern.
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Refactor
Documentation
fetchingTimestamp
for better tracking of asynchronous operations.