WebHost: Set Generator memory limit to 4GiB (#4319)

* WebHost: Set Generator memory limit to 4GiB

* WebHost: make generator memory limit configurable, better naming

* Update WebHostLib/__init__.py

Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com>

* Update docs/webhost configuration sample.yaml

---------

Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com>
This commit is contained in:
black-sliver 2024-12-10 02:44:41 +01:00 committed by GitHub
parent 0b3d34ab24
commit 4a5ba756b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 5 deletions

View File

@ -39,6 +39,8 @@ app.config["SECRET_KEY"] = bytes(socket.gethostname(), encoding="utf-8")
app.config["JOB_THRESHOLD"] = 1 app.config["JOB_THRESHOLD"] = 1
# after what time in seconds should generation be aborted, freeing the queue slot. Can be set to None to disable. # after what time in seconds should generation be aborted, freeing the queue slot. Can be set to None to disable.
app.config["JOB_TIME"] = 600 app.config["JOB_TIME"] = 600
# memory limit for generator processes in bytes
app.config["GENERATOR_MEMORY_LIMIT"] = 4294967296
app.config['SESSION_PERMANENT'] = True app.config['SESSION_PERMANENT'] = True
# waitress uses one thread for I/O, these are for processing of views that then get sent # waitress uses one thread for I/O, these are for processing of views that then get sent

View File

@ -6,6 +6,7 @@ import multiprocessing
import typing import typing
from datetime import timedelta, datetime from datetime import timedelta, datetime
from threading import Event, Thread from threading import Event, Thread
from typing import Any
from uuid import UUID from uuid import UUID
from pony.orm import db_session, select, commit from pony.orm import db_session, select, commit
@ -53,7 +54,21 @@ def launch_generator(pool: multiprocessing.pool.Pool, generation: Generation):
generation.state = STATE_STARTED generation.state = STATE_STARTED
def init_db(pony_config: dict): def init_generator(config: dict[str, Any]) -> None:
try:
import resource
except ModuleNotFoundError:
pass # unix only module
else:
# set soft limit for memory to from config (default 4GiB)
soft_limit = config["GENERATOR_MEMORY_LIMIT"]
old_limit, hard_limit = resource.getrlimit(resource.RLIMIT_AS)
if soft_limit != old_limit:
resource.setrlimit(resource.RLIMIT_AS, (soft_limit, hard_limit))
logging.debug(f"Changed AS mem limit {old_limit} -> {soft_limit}")
del resource, soft_limit, hard_limit
pony_config = config["PONY"]
db.bind(**pony_config) db.bind(**pony_config)
db.generate_mapping() db.generate_mapping()
@ -105,8 +120,8 @@ def autogen(config: dict):
try: try:
with Locker("autogen"): with Locker("autogen"):
with multiprocessing.Pool(config["GENERATORS"], initializer=init_db, with multiprocessing.Pool(config["GENERATORS"], initializer=init_generator,
initargs=(config["PONY"],), maxtasksperchild=10) as generator_pool: initargs=(config,), maxtasksperchild=10) as generator_pool:
with db_session: with db_session:
to_start = select(generation for generation in Generation if generation.state == STATE_STARTED) to_start = select(generation for generation in Generation if generation.state == STATE_STARTED)

View File

@ -27,8 +27,14 @@
# If you wish to deploy, uncomment the following line and set it to something not easily guessable. # If you wish to deploy, uncomment the following line and set it to something not easily guessable.
# SECRET_KEY: "Your secret key here" # SECRET_KEY: "Your secret key here"
# TODO # Slot limit to post a generation to Generator process pool instead of rolling directly in WebHost process
#JOB_THRESHOLD: 2 #JOB_THRESHOLD: 1
# After what time in seconds should generation be aborted, freeing the queue slot. Can be set to None to disable.
#JOB_TIME: 600
# Memory limit for Generator processes in bytes, -1 for unlimited. Currently only works on Linux.
#GENERATOR_MEMORY_LIMIT: 4294967296
# waitress uses one thread for I/O, these are for processing of view that get sent # waitress uses one thread for I/O, these are for processing of view that get sent
#WAITRESS_THREADS: 10 #WAITRESS_THREADS: 10