-
Notifications
You must be signed in to change notification settings - Fork 7.5k
Fix corrupted JSONL metrics file due to concurrent writes #19011
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
Changes from 2 commits
8c643a2
39eec95
4c21e27
1e35220
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |||||
|
|
||||||
| from sglang.srt.managers.io_struct import EmbeddingReqInput, GenerateReqInput | ||||||
| from sglang.srt.server_args import ServerArgs | ||||||
| from sglang.srt.utils.aio_rwlock import RWLock | ||||||
|
|
||||||
| logger = logging.getLogger(__name__) | ||||||
|
|
||||||
|
|
@@ -87,6 +88,7 @@ def __init__( | |||||
|
|
||||||
| # File handler state management | ||||||
| self._current_file_handler = None | ||||||
| self._current_file_lock = RWLock() | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a standard
Suggested change
|
||||||
| self._current_hour_suffix = None | ||||||
|
|
||||||
| def _ensure_file_handler(self, hour_suffix: str): | ||||||
|
|
@@ -135,20 +137,21 @@ async def write_record( | |||||
| current_time = datetime.now() | ||||||
| hour_suffix = current_time.strftime("%Y%m%d_%H") | ||||||
|
|
||||||
| # Ensure correct file handler is open for current hour | ||||||
| self._ensure_file_handler(hour_suffix) | ||||||
| async with self._current_file_lock.writer_lock: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| # Ensure correct file handler is open for current hour | ||||||
| self._ensure_file_handler(hour_suffix) | ||||||
|
|
||||||
| if self._current_file_handler is None: | ||||||
| return | ||||||
| if self._current_file_handler is None: | ||||||
| return | ||||||
|
|
||||||
| metrics_data = self._format_output_data(obj, out_dict) | ||||||
| metrics_data = self._format_output_data(obj, out_dict) | ||||||
|
|
||||||
| def write_file(): | ||||||
| json.dump(metrics_data, self._current_file_handler) | ||||||
| self._current_file_handler.write("\n") | ||||||
| self._current_file_handler.flush() | ||||||
| def write_file(): | ||||||
| json.dump(metrics_data, self._current_file_handler) | ||||||
| self._current_file_handler.write("\n") | ||||||
| self._current_file_handler.flush() | ||||||
|
|
||||||
| await asyncio.to_thread(write_file) | ||||||
| await asyncio.to_thread(write_file) | ||||||
| except Exception as e: | ||||||
| logger.exception(f"Failed to write perf metrics to file: {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.
Since only the writer lock is used in
FileRequestMetricsExporter, a simplerasyncio.Lockwould suffice and be slightly more direct. You can remove this import and use theasynciomodule, which is already imported.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.
@talorabr Can we replace with a simpler asyncio.Lock as suggested