Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
523 changes: 420 additions & 103 deletions lockfiles/st2.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion requirements-pants.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ flex
# gitpython & gitdb are used for pack management
gitdb
gitpython
# st2common/tests/integration/test_util_green.py requires greenlet (as does eventlet)
# st2common/tests/integration/test_util_green.py requires greenlet (as does eventlet and gevent)
gevent
greenlet
gunicorn
jinja2
Expand Down
20 changes: 9 additions & 11 deletions st2api/st2api/cmd/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 The StackStorm Authors.
# Copyright 2020-2026 The StackStorm Authors.
# Copyright 2019 Extreme Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -13,20 +13,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys

# NOTE: It's important that we perform monkey patch as early as possible before any other modules
# are important, otherwise SSL support for MongoDB won't work.
# See https://github.com/StackStorm/st2/issues/4832 and https://github.com/gevent/gevent/issues/1016
# for details.
from st2common.util.monkey_patch import monkey_patch

monkey_patch()

import eventlet
import os
import sys

from oslo_config import cfg
from eventlet import wsgi
from st2common.util import concurrency

from st2common import log as logging
from st2common.service_setup import setup as common_setup
Expand Down Expand Up @@ -79,11 +77,11 @@ def _run_server():

LOG.info("(PID=%s) ST2 API is serving on http://%s:%s.", os.getpid(), host, port)

max_pool_size = eventlet.wsgi.DEFAULT_MAX_SIMULTANEOUS_REQUESTS
worker_pool = eventlet.GreenPool(max_pool_size)
sock = eventlet.listen((host, port))
max_pool_size = concurrency.get_default_green_pool_size()
worker_pool = concurrency.get_green_pool_class()(max_pool_size)
sock = concurrency.listen_server(host, port)

wsgi.server(
concurrency.wsgi_server(
sock, app.setup_app(), custom_pool=worker_pool, log=LOG, log_output=False
)
return 0
Expand Down
27 changes: 14 additions & 13 deletions st2auth/st2auth/cmd/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 The StackStorm Authors.
# Copyright 2020-2026 The StackStorm Authors.
# Copyright 2019 Extreme Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -14,20 +14,18 @@
# limitations under the License.

from st2common.util.monkey_patch import monkey_patch

monkey_patch()

import eventlet
import os
import sys

from oslo_config import cfg
from eventlet import wsgi

from st2common import log as logging
from st2common.service_setup import setup as common_setup
from st2common.service_setup import teardown as common_teardown
from st2common.service_setup import deregister_service
from st2common.util import concurrency
from st2auth import config

config.register_opts(ignore_errors=True)
Expand Down Expand Up @@ -75,29 +73,32 @@ def _run_server():
cert_file_path = os.path.realpath(cfg.CONF.auth.cert)
key_file_path = os.path.realpath(cfg.CONF.auth.key)

if use_ssl and not os.path.isfile(cert_file_path):
raise ValueError('Certificate file "%s" doesn\'t exist' % (cert_file_path))
socket = concurrency.listen(host, port)

if use_ssl and not os.path.isfile(key_file_path):
raise ValueError('Private key file "%s" doesn\'t exist' % (key_file_path))
if use_ssl:
scheme = "https"
if not os.path.isfile(cert_file_path):
raise ValueError(f'Certificate file "{cert_file_path}" does not exist')

socket = eventlet.listen((host, port))
if not os.path.isfile(key_file_path):
raise ValueError(f'Private key file "{key_file_path}" does not exist')

if use_ssl:
socket = eventlet.wrap_ssl(
socket = concurrency.wrap_ssl(
socket, certfile=cert_file_path, keyfile=key_file_path, server_side=True
)
else:
scheme = "http"

LOG.info('ST2 Auth API running in "%s" auth mode', cfg.CONF.auth.mode)
LOG.info(
"(PID=%s) ST2 Auth API is serving on %s://%s:%s.",
os.getpid(),
"https" if use_ssl else "http",
scheme,
host,
port,
)

wsgi.server(socket, app.setup_app(), log=LOG, log_output=False)
concurrency.wsgi_server(socket, app.setup_app(), log=LOG, log_output=False)
return 0


Expand Down
12 changes: 6 additions & 6 deletions st2common/st2common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,8 +759,8 @@ def register_opts(ignore_errors=False):
cfg.BoolOpt(
"use-debugger",
default=True,
help="Enables debugger. Note that using this option changes how the "
"eventlet library is used to support async IO. This could result in "
help="Enables debugger. Note that using this option changes how the "
"concurrency library is used to support async IO. This could result in "
"failures that do not occur under normal operation.",
),
cfg.BoolOpt(
Expand All @@ -769,14 +769,14 @@ def register_opts(ignore_errors=False):
help="Enable code profiler mode. Do not use in production.",
),
cfg.BoolOpt(
"enable-eventlet-blocking-detection",
"enable-concurrency-blocking-detection",
default=False,
help="Enable eventlet blocking detection logic. Do not use in production.",
help="Enable blocking detection logic in concurrency library. Do not use in production.",
),
cfg.FloatOpt(
"eventlet-blocking-detection-resolution",
"concurrency-blocking-detection-resolution",
default=0.5,
help="Resolution in seconds for eventlet blocking detection logic.",
help="Resolution in seconds for blocking detection logic in currency library.",
),
]

Expand Down
33 changes: 12 additions & 21 deletions st2common/st2common/service_setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 The StackStorm Authors.
# Copyright 2020-2026 The StackStorm Authors.
# Copyright 2019 Extreme Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -26,7 +26,7 @@
import logging as stdlib_logging

import six
import eventlet.debug

from oslo_config import cfg
from tooz.coordination import GroupAlreadyExist
from tooz.coordination import GroupNotCreated
Expand All @@ -38,6 +38,7 @@
from st2common.transport.bootstrap_utils import register_kombu_serializers
from st2common.bootstrap import runnersregistrar
from st2common.signal_handlers import register_common_signal_handlers
from st2common.util.concurrency import blocking_detection
from st2common.util.debugging import enable_debugging
from st2common.models.utils.profiling import enable_profiling
from st2common import triggers
Expand Down Expand Up @@ -182,8 +183,7 @@ def setup(
or encoding.lower() not in VALID_UTF8_ENCODINGS
):
LOG.warning(
NON_UTF8_LOCALE_WARNING_MSG
% (fs_encoding, default_encoding, used_locale.strip())
NON_UTF8_LOCALE_WARNING_MSG % (fs_encoding, default_encoding, used_locale.strip())
)

is_debug_enabled = cfg.CONF.debug or cfg.CONF.system.debug
Expand All @@ -197,9 +197,7 @@ def setup(
except KeyError as e:
tb_msg = traceback.format_exc()
if "log.setLevel" in tb_msg:
msg = (
"Invalid log level selected. Log level names need to be all uppercase."
)
msg = "Invalid log level selected. Log level names need to be all uppercase."
msg += "\n\n" + getattr(e, "message", six.text_type(e))
raise KeyError(msg)
else:
Expand All @@ -214,8 +212,7 @@ def setup(
# set to "INFO" and we already log messages with level AUDIT to a special dedicated log
# file.
ignore_audit_log_messages = (
handler.level >= stdlib_logging.INFO
and handler.level < stdlib_logging.AUDIT
handler.level >= stdlib_logging.INFO and handler.level < stdlib_logging.AUDIT
)
if not is_debug_enabled and ignore_audit_log_messages:
try:
Expand All @@ -224,10 +221,7 @@ def setup(
# In case handler doesn't have name assigned, repr would throw
handler_repr = "unknown"

LOG.debug(
'Excluding log messages with level "AUDIT" for handler "%s"'
% (handler_repr)
)
LOG.debug('Excluding log messages with level "AUDIT" for handler "%s"' % (handler_repr))
handler.addFilter(LogLevelFilter(log_levels=exclude_log_levels))

if not is_debug_enabled:
Expand Down Expand Up @@ -285,11 +279,10 @@ def setup(
# modules like jinja, stevedore, etc load files from disk on init which is slow and will be
# detected as blocking operation, but this is not really an issue inside the service startup /
# init phase.
if cfg.CONF.enable_eventlet_blocking_detection:
print("Eventlet long running / blocking operation detection logic enabled")
print(cfg.CONF.eventlet_blocking_detection_resolution)
eventlet.debug.hub_blocking_detection(
state=True, resolution=cfg.CONF.eventlet_blocking_detection_resolution
if cfg.CONF.enable_concurrency_blocking_detection:
blocking_detection(
cfg.CONF.enable_concurrency_blocking_detection,
cfg.CONF.concurrency_blocking_detection_resolution,
)


Expand Down Expand Up @@ -354,9 +347,7 @@ def deregister_service(service, start_heart=True):
coordinator = coordination.get_coordinator(start_heart=start_heart)

member_id = coordination.get_member_id()
LOG.debug(
'Leaving service registry group "%s" as member_id "%s"' % (group_id, member_id)
)
LOG.debug('Leaving service registry group "%s" as member_id "%s"' % (group_id, member_id))
try:
coordinator.leave_group(group_id).get()
except (GroupNotCreated, MemberNotJoined):
Expand Down
Loading