mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-02 13:48:09 +00:00
Skip lock acquisition in CrewTrainingHandler.load when file is missing (#5935)
Every agent kickoff calls _use_trained_data, which calls CrewTrainingHandler(...).load(). Since #4827 wrapped load() in store_lock, that means every kickoff acquires the cross-process (Redis-backed when REDIS_URL is set) lock even on deployments that never train and have no trained-agents file on disk. Move the missing/empty-file short-circuit above store_lock so the lock is only acquired when there is actually a file to read. save() and the real read remain locked.
This commit is contained in:
@@ -167,17 +167,12 @@ class PickleHandler:
|
||||
Returns:
|
||||
The data loaded from the file.
|
||||
"""
|
||||
with store_lock(f"file:{os.path.realpath(self.file_path)}"):
|
||||
if (
|
||||
not os.path.exists(self.file_path)
|
||||
or os.path.getsize(self.file_path) == 0
|
||||
):
|
||||
return {}
|
||||
if not os.path.exists(self.file_path):
|
||||
return {}
|
||||
|
||||
with open(self.file_path, "rb") as file:
|
||||
try:
|
||||
with store_lock(f"file:{os.path.realpath(self.file_path)}"):
|
||||
try:
|
||||
with open(self.file_path, "rb") as file:
|
||||
return pickle.load(file) # noqa: S301
|
||||
except EOFError:
|
||||
return {}
|
||||
except Exception:
|
||||
raise
|
||||
except (FileNotFoundError, EOFError):
|
||||
return {}
|
||||
|
||||
@@ -1083,6 +1083,21 @@ def test_agent_use_trained_data_honors_env_var(crew_training_handler, monkeypatc
|
||||
)
|
||||
|
||||
|
||||
def test_agent_use_trained_data_skips_load_when_file_missing(tmp_path, monkeypatch):
|
||||
monkeypatch.setenv(
|
||||
"CREWAI_TRAINED_AGENTS_FILE", str(tmp_path / "does_not_exist.pkl")
|
||||
)
|
||||
agent = Agent(role="researcher", goal="test goal", backstory="test backstory")
|
||||
|
||||
with patch(
|
||||
"crewai.utilities.file_handler.store_lock",
|
||||
side_effect=AssertionError("kickoff acquired lock with no trained-agents file"),
|
||||
):
|
||||
result = agent._use_trained_data(task_prompt="What is 1 + 1?")
|
||||
|
||||
assert result == "What is 1 + 1?"
|
||||
|
||||
|
||||
def test_agent_max_retry_limit():
|
||||
agent = Agent(
|
||||
role="test role",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
@@ -53,3 +54,23 @@ class InternalCrewTrainingHandler(unittest.TestCase):
|
||||
# Assert that the new agent and data are appended correctly
|
||||
data = self.handler.load()
|
||||
assert data[agent_id][train_iteration] == new_data
|
||||
|
||||
def test_load_missing_file_does_not_acquire_lock(self):
|
||||
handler = CrewTrainingHandler(self.temp_file.name + ".missing")
|
||||
|
||||
with patch(
|
||||
"crewai.utilities.file_handler.store_lock",
|
||||
side_effect=AssertionError("load() acquired lock for missing file"),
|
||||
):
|
||||
assert handler.load() == {}
|
||||
|
||||
def test_load_acquires_lock_for_zero_size_file(self):
|
||||
# Empty file mimics a concurrent save() mid-truncation (open "wb").
|
||||
assert os.path.getsize(self.temp_file.name) == 0
|
||||
|
||||
with patch(
|
||||
"crewai.utilities.file_handler.store_lock",
|
||||
side_effect=AssertionError("load() short-circuited on size 0"),
|
||||
):
|
||||
with self.assertRaises(AssertionError):
|
||||
self.handler.load()
|
||||
|
||||
Reference in New Issue
Block a user