mirror of
https://github.com/element-hq/synapse.git
synced 2026-09-25 22:04:00 +00:00
### Summary Resolves #18308. Makes the `TaskScheduler`'s maximum concurrent running tasks configurable via `task_scheduler.max_concurrent_tasks` in the homeserver configuration and defaults it to `2` (reduced from the previous hardcoded limit of `5`). ### Motivation Twisted's `adbapi.ConnectionPool` defaults to 5 database connections (`cp_max=5`). When the `TaskScheduler` previously executed up to 5 tasks concurrently, it could exhaust the entire database connection pool, starving regular API and synchronization requests on smaller homeserver instances. Lowering the default to 2 preserves at least 3 connections for foreground requests while allowing concurrent tasks to progress, and gives administrators the ability to tune the limit according to their host and connection pool sizing. ### Changes - Added `TaskSchedulerConfig` (`task_scheduler.max_concurrent_tasks`) with validation (must be a positive integer) and registered it in `HomeServerConfig`. - Updated `TaskScheduler` to enforce the configured concurrency limit and updated class default to 2. - Updated config documentation and JSON schema. - Added config tests in `tests/config/test_task_scheduler_config.py` and updated unit tests in `tests/util/test_task_scheduler.py`. - Added newsfragment in `changelog.d/18308.feature`. --------- Signed-off-by: nevil06 <nevilansondsouza@gmail.com> Co-authored-by: Devon Hudson <devonhudson@librem.one>
55 lines
2.1 KiB
Python
55 lines
2.1 KiB
Python
#
|
|
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
#
|
|
# Copyright 2026 Nevil Anson Dsouza
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
# License, or (at your option) any later version.
|
|
#
|
|
# See the GNU Affero General Public License for more details:
|
|
# <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
#
|
|
#
|
|
from synapse.config._base import ConfigError, RootConfig
|
|
from synapse.config.homeserver import HomeServerConfig
|
|
from synapse.config.task_scheduler import TaskSchedulerConfig
|
|
|
|
from tests.unittest import TestCase
|
|
from tests.utils import default_config
|
|
|
|
|
|
class TaskSchedulerConfigTestCase(TestCase):
|
|
def test_default_configuration(self) -> None:
|
|
config_dict = default_config(server_name="test")
|
|
config = HomeServerConfig()
|
|
config.parse_config_dict(config_dict, "", "")
|
|
self.assertEqual(config.task_scheduler.max_concurrent_tasks, 5)
|
|
|
|
def test_custom_configuration(self) -> None:
|
|
config_dict = default_config(server_name="test")
|
|
config_dict["task_scheduler"] = {"max_concurrent_tasks": 4}
|
|
config = HomeServerConfig()
|
|
config.parse_config_dict(config_dict, "", "")
|
|
self.assertEqual(config.task_scheduler.max_concurrent_tasks, 4)
|
|
|
|
def test_invalid_configuration(self) -> None:
|
|
config = TaskSchedulerConfig(RootConfig())
|
|
with self.assertRaises(ConfigError):
|
|
config.read_config({"task_scheduler": {"max_concurrent_tasks": 0}})
|
|
|
|
with self.assertRaises(ConfigError):
|
|
config.read_config({"task_scheduler": {"max_concurrent_tasks": -1}})
|
|
|
|
with self.assertRaises(ConfigError):
|
|
config.read_config(
|
|
{"task_scheduler": {"max_concurrent_tasks": "not-an-int"}}
|
|
)
|
|
|
|
with self.assertRaises(ConfigError):
|
|
config.read_config({"task_scheduler": {"max_concurrent_tasks": True}})
|
|
|
|
with self.assertRaises(ConfigError):
|
|
config.read_config({"task_scheduler": "not-a-dict"})
|