From 415420cc8ff6ecd2a1c39e0ff66066ba691f5874 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Mon, 6 May 2024 15:10:26 -0700 Subject: [PATCH] Use entry_points for server executables The old [files]scripts method of specifying executable Python scripts triggers some legacy easy-install-like mode for editable installs, which relies on pkg_resources. Recent versions of setuptools (67.5.0+) have started emitting warnings when importing pkg_resources, which in turn cause quite noticeable slowdowns in process startup. This is particularly prominant on py312, which stopped pre-installing (an often older version of) setuptools in new venvs. See also: - https://github.com/python/cpython/issues/95299 - https://github.com/pypa/setuptools/pull/3843 - https://github.com/pypa/setuptools/issues/3966 Now, use [entry_points]console_scripts to specify these executables, which does not use pkg_resources in the generated script files. Change-Id: Ifcc8138e7b55d5b82bea0d411ec6bfcca2c77c83 --- bin/swift-account-server | 7 ++----- bin/swift-container-server | 7 ++----- bin/swift-object-server | 8 +------- bin/swift-proxy-server | 7 ++----- setup.cfg | 10 +++++----- swift/account/server.py | 13 ++++++++++++- swift/container/server.py | 13 ++++++++++++- swift/obj/server.py | 15 ++++++++++++++- swift/proxy/server.py | 13 ++++++++++++- 9 files changed, 62 insertions(+), 31 deletions(-) diff --git a/bin/swift-account-server b/bin/swift-account-server index f7e44d6d88..729d973fae 100755 --- a/bin/swift-account-server +++ b/bin/swift-account-server @@ -14,10 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys -from swift.common.utils import parse_options -from swift.common.wsgi import run_wsgi +from swift.account import server if __name__ == '__main__': - conf_file, options = parse_options(test_config=True) - sys.exit(run_wsgi(conf_file, 'account-server', **options)) + server.main() diff --git a/bin/swift-container-server b/bin/swift-container-server index d76fe1767e..5f2c3e6a97 100755 --- a/bin/swift-container-server +++ b/bin/swift-container-server @@ -14,10 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys -from swift.common.utils import parse_options -from swift.common.wsgi import run_wsgi +from swift.container import server if __name__ == '__main__': - conf_file, options = parse_options(test_config=True) - sys.exit(run_wsgi(conf_file, 'container-server', **options)) + server.main() diff --git a/bin/swift-object-server b/bin/swift-object-server index d858e4bcb9..6f968a0b50 100755 --- a/bin/swift-object-server +++ b/bin/swift-object-server @@ -14,14 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys -from swift.common.utils import parse_options -from swift.common.wsgi import run_wsgi from swift.obj import server if __name__ == '__main__': - conf_file, options = parse_options(test_config=True) - sys.exit(run_wsgi(conf_file, 'object-server', - global_conf_callback=server.global_conf_callback, - **options)) + server.main() diff --git a/bin/swift-proxy-server b/bin/swift-proxy-server index 4589982482..1a11eb70a1 100755 --- a/bin/swift-proxy-server +++ b/bin/swift-proxy-server @@ -14,10 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys -from swift.common.utils import parse_options -from swift.common.wsgi import run_wsgi +from swift.proxy import server if __name__ == '__main__': - conf_file, options = parse_options(test_config=True) - sys.exit(run_wsgi(conf_file, 'proxy-server', **options)) + server.main() diff --git a/setup.cfg b/setup.cfg index 321222e269..77f61949ab 100644 --- a/setup.cfg +++ b/setup.cfg @@ -44,12 +44,10 @@ scripts = bin/swift-account-info bin/swift-account-reaper bin/swift-account-replicator - bin/swift-account-server bin/swift-config bin/swift-container-auditor bin/swift-container-info bin/swift-container-replicator - bin/swift-container-server bin/swift-container-sharder bin/swift-container-sync bin/swift-container-updater @@ -67,11 +65,9 @@ scripts = bin/swift-object-replicator bin/swift-object-reconstructor bin/swift-object-relinker - bin/swift-object-server bin/swift-object-updater bin/swift-oldies bin/swift-orphans - bin/swift-proxy-server bin/swift-recon bin/swift-recon-cron bin/swift-ring-builder @@ -91,8 +87,12 @@ keystone = [entry_points] console_scripts = - swift-manage-shard-ranges = swift.cli.manage_shard_ranges:main + swift-account-server = swift.account.server:main swift-container-deleter = swift.cli.container_deleter:main + swift-container-server = swift.container.server:main + swift-manage-shard-ranges = swift.cli.manage_shard_ranges:main + swift-object-server = swift.obj.server:main + swift-proxy-server = swift.proxy.server:main swift-reload = swift.cli.reload:main paste.app_factory = diff --git a/swift/account/server.py b/swift/account/server.py index 02c16aebed..35849e6113 100644 --- a/swift/account/server.py +++ b/swift/account/server.py @@ -15,6 +15,7 @@ import json import os +import sys import time import traceback @@ -30,7 +31,7 @@ from swift.common.request_helpers import get_param, \ from swift.common.utils import get_logger, hash_path, public, \ Timestamp, storage_directory, config_true_value, \ timing_stats, replication, get_log_line, \ - config_fallocate_value, fs_has_free_space + config_fallocate_value, fs_has_free_space, parse_options from swift.common.constraints import valid_timestamp, check_utf8, \ check_drive, AUTO_CREATE_ACCOUNT_PREFIX from swift.common import constraints @@ -43,6 +44,7 @@ from swift.common.swob import HTTPAccepted, HTTPBadRequest, \ HTTPPreconditionFailed, HTTPConflict, Request, \ HTTPInsufficientStorage, HTTPException, wsgi_to_str from swift.common.request_helpers import is_sys_or_user_meta +from swift.common.wsgi import run_wsgi def get_account_name_and_placement(req): @@ -339,3 +341,12 @@ def app_factory(global_conf, **local_conf): conf = global_conf.copy() conf.update(local_conf) return AccountController(conf) + + +def main(): + conf_file, options = parse_options(test_config=True) + sys.exit(run_wsgi(conf_file, 'account-server', **options)) + + +if __name__ == '__main__': + main() diff --git a/swift/container/server.py b/swift/container/server.py index a27df6e3ad..75ec51a404 100644 --- a/swift/container/server.py +++ b/swift/container/server.py @@ -15,6 +15,7 @@ import json import os +import sys import time import traceback @@ -38,7 +39,7 @@ from swift.common.utils import get_logger, hash_path, public, \ config_true_value, timing_stats, replication, \ override_bytes_from_content_type, get_log_line, \ config_fallocate_value, fs_has_free_space, list_from_csv, \ - ShardRange + ShardRange, parse_options from swift.common.constraints import valid_timestamp, check_utf8, \ check_drive, AUTO_CREATE_ACCOUNT_PREFIX from swift.common.bufferedhttp import http_connect @@ -53,6 +54,7 @@ from swift.common.swob import HTTPAccepted, HTTPBadRequest, HTTPConflict, \ HTTPPreconditionFailed, HTTPMethodNotAllowed, Request, Response, \ HTTPInsufficientStorage, HTTPException, HTTPMovedPermanently, \ wsgi_to_str, str_to_wsgi +from swift.common.wsgi import run_wsgi def gen_resp_headers(info, is_deleted=False): @@ -1048,3 +1050,12 @@ def app_factory(global_conf, **local_conf): conf = global_conf.copy() conf.update(local_conf) return ContainerController(conf) + + +def main(): + conf_file, options = parse_options(test_config=True) + sys.exit(run_wsgi(conf_file, 'container-server', **options)) + + +if __name__ == '__main__': + main() diff --git a/swift/obj/server.py b/swift/obj/server.py index 956db55dfd..df170ae194 100644 --- a/swift/obj/server.py +++ b/swift/obj/server.py @@ -21,6 +21,7 @@ from six.moves.urllib.parse import unquote import json import os import multiprocessing +import sys import time import traceback import socket @@ -34,7 +35,7 @@ from swift.common.utils import public, get_logger, \ get_expirer_container, parse_mime_headers, \ iter_multipart_mime_documents, extract_swift_bytes, safe_json_loads, \ config_auto_int_value, split_path, get_redirect_data, \ - normalize_timestamp, md5 + normalize_timestamp, md5, parse_options from swift.common.bufferedhttp import http_connect from swift.common.constraints import check_object_creation, \ valid_timestamp, check_utf8, AUTO_CREATE_ACCOUNT_PREFIX @@ -58,6 +59,7 @@ from swift.common.swob import HTTPAccepted, HTTPBadRequest, HTTPCreated, \ HTTPClientDisconnect, HTTPMethodNotAllowed, Request, Response, \ HTTPInsufficientStorage, HTTPForbidden, HTTPException, HTTPConflict, \ HTTPServerError, bytes_to_wsgi, wsgi_to_bytes, wsgi_to_str, normalize_etag +from swift.common.wsgi import run_wsgi from swift.obj.diskfile import RESERVED_DATAFILE_META, DiskFileRouter from swift.obj.expirer import build_task_obj, embed_expirer_bytes_in_ctype, \ X_DELETE_TYPE @@ -1454,3 +1456,14 @@ def app_factory(global_conf, **local_conf): conf = global_conf.copy() conf.update(local_conf) return ObjectController(conf) + + +def main(): + conf_file, options = parse_options(test_config=True) + sys.exit(run_wsgi(conf_file, 'object-server', + global_conf_callback=global_conf_callback, + **options)) + + +if __name__ == '__main__': + main() diff --git a/swift/proxy/server.py b/swift/proxy/server.py index 3615290af9..732c5823a4 100644 --- a/swift/proxy/server.py +++ b/swift/proxy/server.py @@ -36,7 +36,8 @@ from swift.common.utils import Watchdog, get_logger, \ get_remote_client, split_path, config_true_value, generate_trans_id, \ affinity_key_function, affinity_locality_predicate, list_from_csv, \ parse_prefixed_conf, config_auto_int_value, node_to_string, \ - config_request_node_count_value, config_percent_value, cap_length + config_request_node_count_value, config_percent_value, cap_length, \ + parse_options from swift.common.registry import register_swift_info from swift.common.constraints import check_utf8, valid_api_version from swift.proxy.controllers import AccountController, ContainerController, \ @@ -49,6 +50,7 @@ from swift.common.swob import HTTPBadRequest, HTTPForbidden, \ HTTPServerError, HTTPException, Request, HTTPServiceUnavailable, \ wsgi_to_str from swift.common.exceptions import APIVersionError +from swift.common.wsgi import run_wsgi # List of entry points for mandatory middlewares. @@ -818,3 +820,12 @@ def app_factory(global_conf, **local_conf): app = Application(conf) app.check_config() return app + + +def main(): + conf_file, options = parse_options(test_config=True) + sys.exit(run_wsgi(conf_file, 'proxy-server', **options)) + + +if __name__ == '__main__': + main()