Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion evalscope/utils/io_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import string
import unicodedata
import yaml
import time
import random
from datetime import datetime
from io import BytesIO
from PIL import Image
Expand Down Expand Up @@ -208,6 +210,7 @@ def dump_jsonl_data(

Raises:
ValueError: When *jsonl_file* is empty or ``None``.
PermissionError: When file is locked.
"""
if not jsonl_file:
raise ValueError('output file must be provided.')
Expand All @@ -222,7 +225,17 @@ def dump_jsonl_data(

mode = 'w' if dump_mode == DumpMode.OVERWRITE else 'a'
with jsonl.open(jsonl_file, mode=mode) as writer:
writer.write_all(data_list)
max_retries = 50
for attempt in range(max_retries):
try:
with jsonl.open(jsonl_file, mode=mode) as writer:
writer.write_all(data_list)
break
except PermissionError as e:
if attempt == max_retries - 1:
logger.error(f'Failed to write to "{jsonl_file}" after "{max_retries}" attempts due to file locking: {e}')
raise
time.sleep(0.1 + random.uniform(0.01, 0.1) * attempt)
Comment on lines +228 to +238

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The retry logic is nested inside an outer with jsonl.open(jsonl_file, mode=mode) as writer: statement (line 227). This causes two major issues:

  1. Immediate Failure on Initial Open: If the initial file open on line 227 fails with a PermissionError, the retry loop is never reached, and the error is raised immediately.
  2. Nested File Locking: If the initial open succeeds, the code inside the loop tries to open the same file again on line 231. On Windows, this nested open will fail with a PermissionError due to file locking (sharing violation), making the write fail every time.

To fix this, the outer with statement on line 227 should be removed entirely, and the retry loop should wrap the file opening and writing directly at the outer level:

    mode = 'w' if dump_mode == DumpMode.OVERWRITE else 'a'
    max_retries = 50
    for attempt in range(max_retries):
        try:
            with jsonl.open(jsonl_file, mode=mode) as writer:
                writer.write_all(data_list)
            break
        except PermissionError as e:
            if attempt == max_retries - 1:
                logger.error(f'Failed to write to "{jsonl_file}" after "{max_retries}" attempts due to file locking: {e}')
                raise
            time.sleep(0.1 + random.uniform(0.01, 0.1) * attempt)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. if initial try fails it will simply go under permissionerror block, sleep and re attempt
  2. break stops the for loop only when a write is successfull



# ---------------------------------------------------------------------------
Expand Down