Skip to content

Commit 58281c1

Browse files
committed
mgr/rest: Trim request array and limit size
Presently, the requests array in the REST module has the potential to grow indefinitely, leading to excessive memory consumption, particularly when dealing with lengthy and intricate request results. To address this issue, a limit will be imposed on the requests array within the REST module. This limitation will be governed by the `mgr/restful/x/max_requests` configuration parameter specific to the REST module. when submit_request called we will check request array if exceed max_request option if it does we will check if the future trimmed request finished and log error message in case we are trimming un-finished requests. Fixes: https://tracker.ceph.com/issues/59580 Signed-off-by: Nitzan Mordechai <[email protected]>
1 parent 44747ff commit 58281c1

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

src/pybind/mgr/restful/module.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import traceback
1313
import socket
1414
import fcntl
15+
from typing import cast
1516

1617
from . import common
1718
from . import context
@@ -197,6 +198,7 @@ class Module(MgrModule):
197198
{'name': 'server_port'},
198199
{'name': 'key_file'},
199200
{'name': 'enable_auth', 'type': 'bool', 'default': True},
201+
{'name': 'max_requests', 'type': 'int', 'default': 500},
200202
]
201203

202204
COMMANDS = [
@@ -243,6 +245,7 @@ def __init__(self, *args, **kwargs):
243245

244246
self.stop_server = False
245247
self.serve_event = threading.Event()
248+
self.max_requests = cast(int, self.get_localized_module_option('max_requests', 500))
246249

247250

248251
def serve(self):
@@ -599,6 +602,16 @@ def submit_request(self, _request, **kwargs):
599602
with self.requests_lock:
600603
request = CommandsRequest(_request)
601604
self.requests.append(request)
605+
if len(self.requests) > self.max_requests:
606+
req_to_trim = 0
607+
for i, req in enumerate(self.requests):
608+
if req.is_finished():
609+
self.log.error("Trimmed one finished request due to exceeded maximum requests limit")
610+
req_to_trim = i
611+
break
612+
else:
613+
self.log.error("Trimmed the oldest unfinished request due to exceeded maximum requests limit")
614+
self.requests.pop(req_to_trim)
602615
if kwargs.get('wait', 0):
603616
while not request.is_finished():
604617
time.sleep(0.001)

0 commit comments

Comments
 (0)