Prompt
When designing concurrent systems, implement comprehensive safety patterns that handle resource lifecycle management, race conditions, and proper cleanup mechanisms. This includes setting resource limits to prevent exhaustion, implementing timeout-based cleanup for idle resources, and handling database race conditions with proper rollback and retry logic.
Key patterns to implement:
- Resource Lifecycle Management: Use structured cleanup with limits and timeouts
class ResourceManager: def __init__(self): self.resources_by_key = {} # Group resources by identity self._cleanup_task = asyncio.create_task(self._periodic_cleanup()) async def _periodic_cleanup(self): """Periodically clean up idle resources.""" while True: await asyncio.sleep(CLEANUP_INTERVAL) await self._cleanup_idle_resources() async def get_resource(self, key, params): # Check limits before creating new resources if len(self.resources_by_key.get(key, {})) >= MAX_RESOURCES_PER_KEY: # Remove oldest resource await self._cleanup_oldest_resource(key) - Race Condition Handling: Implement proper exception handling with rollback and retry
async def create_resource(name, session): try: # Check if resource exists existing = await get_resource_by_name(name, session) if existing: return existing # Create new resource resource = Resource(name=name) session.add(resource) await session.commit() return resource except IntegrityError: # Handle race condition - another worker created it await session.rollback() existing = await get_resource_by_name(name, session) if existing: return existing raise # Re-raise if no resource found after rollback - Test Concurrent Scenarios: Use
asyncio.gather()to test real concurrent behavior@pytest.mark.asyncio async def test_concurrent_resource_creation(): """Test multiple concurrent calls handle race conditions properly.""" tasks = [ create_resource("shared_name", session1), create_resource("shared_name", session2) ] results = await asyncio.gather(*tasks, return_exceptions=True) # Verify both succeed or handle conflicts gracefully
Always consider the impact of automatic resource cleanup on user experience and provide clear boundaries for resource limits to prevent unexpected behavior disruptions.