BUG: make log rotation safe across Windows processes - #5303
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces cross-platform, cross-process log rotation safety by implementing a shared _SafeFileRotationMixin that uses platform-native file locking (msvcrt on Windows and fcntl on Unix) and tracks rotation state via a shared lock file. It updates the rotating file handlers to inherit from this mixin and adds comprehensive unit tests to verify the Windows fallback and rotation coordination. The feedback highlights a potential file descriptor leak in _acquire_rotation_lock if the locking mechanism raises an exception, suggesting wrapping the lock acquisition in a try...except block to ensure the file descriptor is closed.
| def _acquire_rotation_lock(self): | ||
| lock_fd = open(self._lock_path, "r+b") | ||
| if msvcrt is not None: | ||
| lock_fd.seek(0) | ||
| msvcrt.locking(lock_fd.fileno(), msvcrt.LK_LOCK, 1) | ||
| else: | ||
| fcntl.flock(lock_fd, fcntl.LOCK_EX) | ||
| return lock_fd |
There was a problem hiding this comment.
If msvcrt.locking or fcntl.flock raises an exception (for example, due to a timeout or locking conflict), the newly opened lock_fd will be leaked because the caller's try...finally block in doRollover is not entered when _acquire_rotation_lock raises an exception. To prevent file descriptor leaks, wrap the locking logic in a try...except block and close lock_fd before re-raising the exception.
| def _acquire_rotation_lock(self): | |
| lock_fd = open(self._lock_path, "r+b") | |
| if msvcrt is not None: | |
| lock_fd.seek(0) | |
| msvcrt.locking(lock_fd.fileno(), msvcrt.LK_LOCK, 1) | |
| else: | |
| fcntl.flock(lock_fd, fcntl.LOCK_EX) | |
| return lock_fd | |
| def _acquire_rotation_lock(self): | |
| lock_fd = open(self._lock_path, "r+b") | |
| try: | |
| if msvcrt is not None: | |
| lock_fd.seek(0) | |
| msvcrt.locking(lock_fd.fileno(), msvcrt.LK_LOCK, 1) | |
| else: | |
| fcntl.flock(lock_fd, fcntl.LOCK_EX) | |
| return lock_fd | |
| except Exception: | |
| lock_fd.close() | |
| raise |
Summary
msvcrt.lockingon Windows while retainingfcntl.flockon POSIXFixes #5284.
Validation
xinference/deploy/test/test_log_rotation.py: 35 passedThe regression tests simulate Windows lock and rename behavior on macOS, including two handlers racing on size and midnight rotation. A Windows host end-to-end run was not available.