Skip to content

Commit 616f8d6

Browse files
committed
Limit the max open files of state sync cache db
Fixes #1479
1 parent 7e3d7b1 commit 616f8d6

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

eth/db/backends/level.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ class LevelDB(BaseAtomicDB):
2828
logger = logging.getLogger("eth.db.backends.LevelDB")
2929

3030
# Creates db as a class variable to avoid level db lock error
31-
def __init__(self, db_path: Path = None) -> None:
31+
def __init__(self,
32+
db_path: Path=None,
33+
max_open_files: int=None) -> None:
3234
if not db_path:
3335
raise TypeError("Please specifiy a valid path for your database.")
3436
try:
@@ -39,7 +41,12 @@ def __init__(self, db_path: Path = None) -> None:
3941
"LevelDB requires the plyvel library which is not available for import."
4042
)
4143
self.db_path = db_path
42-
self.db = plyvel.DB(str(db_path), create_if_missing=True, error_if_exists=False)
44+
self.db = plyvel.DB(
45+
str(db_path),
46+
create_if_missing=True,
47+
error_if_exists=False,
48+
max_open_files=max_open_files
49+
)
4350

4451
def __getitem__(self, key: bytes) -> bytes:
4552
v = self.db.get(key)

trinity/sync/full/state.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
HexaryTrieSync,
6363
SyncRequest,
6464
)
65+
from trinity.utils.os import get_open_fd_limit
6566
from trinity.utils.timer import Timer
6667

6768

@@ -85,8 +86,17 @@ def __init__(self,
8586
# We use a LevelDB instance for the nodes cache because a full state download, if run
8687
# uninterrupted will visit more than 180M nodes, making an in-memory cache unfeasible.
8788
self._nodes_cache_dir = tempfile.TemporaryDirectory(prefix="pyevm-state-sync-cache")
89+
90+
# Allow the LevelDB instance to consume half of the entire file descriptor limit that
91+
# the OS permits. Let the other half be reserved for other db access, networking etc.
92+
max_open_files = get_open_fd_limit() // 2
93+
8894
self.scheduler = StateSync(
89-
root_hash, account_db, LevelDB(cast(Path, self._nodes_cache_dir.name)), self.logger)
95+
root_hash,
96+
account_db,
97+
LevelDB(Path(self._nodes_cache_dir.name), max_open_files),
98+
self.logger
99+
)
90100
self.request_tracker = TrieNodeRequestTracker(self._reply_timeout, self.logger)
91101
self._peer_missing_nodes: Dict[ETHPeer, Set[Hash32]] = collections.defaultdict(set)
92102

trinity/utils/os.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import resource
2+
3+
4+
def get_open_fd_limit() -> int:
5+
"""
6+
Return the OS soft limit of open file descriptors per process.
7+
"""
8+
soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE)
9+
return soft_limit

0 commit comments

Comments
 (0)