-
Notifications
You must be signed in to change notification settings - Fork 164
refactor(BA-4092): Refactor VFolder purge API to Service-Repository pattern #8334
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
Conversation
4e6287c to
c78861d
Compare
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.
Pull request overview
This PR refactors the VFolder purge API to follow the Action-Service-Repository pattern, replacing direct database access in the API handler with a properly layered implementation.
Changes:
- Introduces
PurgeVFolderActionandPurgeVFolderActionResultclasses for the action layer - Adds
purge()method toVFolderServicethat delegates to the repository - Implements
purge_vfolder()inVfolderRepositorywith status validation using thePurgerpattern - Registers
purge_vfolderprocessor inVFolderProcessors - Updates API handler to use the processor instead of direct database operations
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/ai/backend/manager/services/vfolder/actions/base.py |
Adds PurgeVFolderAction and PurgeVFolderActionResult action classes with appropriate permission types |
src/ai/backend/manager/services/vfolder/services/vfolder.py |
Implements purge() method in VFolderService that delegates to repository |
src/ai/backend/manager/services/vfolder/processors/vfolder.py |
Registers purge_vfolder processor with action monitors |
src/ai/backend/manager/repositories/vfolder/repository.py |
Implements purge_vfolder() with status validation and execute_purger usage |
src/ai/backend/manager/api/vfolder.py |
Refactors API handler to use processor, removes direct DB access and unused imports |
tests/unit/manager/services/vfolder/test_vfolder_service.py |
Adds comprehensive service layer tests verifying delegation and exception propagation |
tests/unit/manager/repositories/vfolder/test_vfolder_repository.py |
Adds comprehensive repository layer tests for various status scenarios |
tests/unit/manager/services/vfolder/BUILD |
Adds BUILD file for test discovery |
changes/8317.misc.md |
Documents the refactoring change |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if vfolder_data is None: | ||
| raise VFolderNotFound(extra_data=str(vfolder_uuid)) |
Copilot
AI
Jan 27, 2026
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.
This null check is unreachable because get_by_id on line 429 raises VFolderNotFound when the vfolder doesn't exist - it never returns None. The exception is already raised by get_by_id, so this check is redundant and can be removed.
| if vfolder_data is None: | |
| raise VFolderNotFound(extra_data=str(vfolder_uuid)) |
tests/unit/manager/repositories/vfolder/test_vfolder_repository.py
Outdated
Show resolved
Hide resolved
tests/unit/manager/repositories/vfolder/test_vfolder_repository.py
Outdated
Show resolved
Hide resolved
| ) | ||
| ) | ||
| except VFolderInvalidParameter as e: | ||
| raise InvalidAPIParameters(str(e)) |
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.
I'm just curious, why do we need to convert VFolderInvalidParameter to InvalidAPIParameters?
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.
I assume that we keep InvalidAPIParameters for error message compatibility
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.
I think the error message could be updated.
Both errors are same HTTP response code, so I think we don't this need this conversion
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.
Please check it once. @fregataa
| ) | ||
| ) | ||
| except VFolderInvalidParameter as e: | ||
| raise InvalidAPIParameters(str(e)) |
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.
Please check it once. @fregataa
| vfolder_id = uuid.uuid4() | ||
| await self._create_vfolder_in_db( | ||
| db_with_cleanup, | ||
| vfolder_id=vfolder_id, | ||
| domain_name=test_domain_name, | ||
| user_id=test_user, | ||
| status=status, | ||
| ) |
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.
Please put anything related to this situation in the fixture.
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.
it has to use a parameterized input (status). Is there any example to setup fixtures with parameters?
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.
I updated this part
…itory pattern - Add PurgeVFolderAction and PurgeVFolderActionResult classes - Add purge() method to VFolderService with status validation - Add purge_vfolder() method to VfolderRepository using execute_purger - Register purge_vfolder processor in VFolderProcessors - Update API handler to use processor instead of direct DB access
…tory Move VFolderNotFound and VFolderInvalidParameter validation from VFolderService.purge() to VfolderRepository.purge_vfolder() for cleaner separation of concerns. - Repository now validates vfolder existence and purgable status - Service layer simplified to delegate to repository - Added unit tests for both service and repository layers
Add test_purge_vfolder_invalid_status to verify VFolderInvalidParameter is raised when attempting to purge vfolders with non-purgable status (READY, PERFORMING, CLONING, MOUNTED, DELETE_ONGOING, DELETE_ERROR).
Clarify why get_by_id() is called before execute_purger() - it's needed to validate vfolder status since execute_purger() only deletes by PK without checking status.
- Remove @pytest.mark.asyncio decorators (auto-detected by pytest) - Move all imports to top of file - Convert _create_vfolder_data helper to sample_vfolder_data fixture
- Merge purgable/non_purgable fixtures into single vfolder_in_db - Use indirect parametrization to pass status to fixture - Return only vfolder_id from fixture (status not needed)
…atus - Replace VFolderInvalidParameter with VFolderFilterStatusFailed in repository purge_vfolder() for consistency with existing error types - Remove try-except in API handler since VFolderFilterStatusFailed already inherits from HTTPBadRequest - Update tests accordingly
269c3ca to
a1a1529
Compare
resolves #8317 (BA-4092)
Changes
Test Coverage
Service Layer (
VFolderService.purge())test_purge_vfolder_successPurgeVFolderActionResulttest_purge_vfolder_not_found_propagatesVFolderNotFoundexception from repositorytest_purge_vfolder_invalid_status_propagatesVFolderInvalidParameterexception from repositoryRepository Layer (
VfolderRepository.purge_vfolder())test_purge_vfolder_success[delete_complete]DELETE_COMPLETEstatus, verifies deletion from DBtest_purge_vfolder_success[delete_pending]DELETE_PENDINGstatus, verifies deletion from DBtest_purge_vfolder_not_foundVFolderNotFoundwhen vfolder doesn't existtest_purge_vfolder_invalid_status[ready]VFolderInvalidParameterforREADYstatustest_purge_vfolder_invalid_status[performing]VFolderInvalidParameterforPERFORMINGstatustest_purge_vfolder_invalid_status[cloning]VFolderInvalidParameterforCLONINGstatustest_purge_vfolder_invalid_status[mounted]VFolderInvalidParameterforMOUNTEDstatustest_purge_vfolder_invalid_status[delete_ongoing]VFolderInvalidParameterforDELETE_ONGOINGstatustest_purge_vfolder_invalid_status[delete_error]VFolderInvalidParameterforDELETE_ERRORstatusChecklist: (if applicable)
ai.backend.testdocsdirectory