Skip to content

Commit

Permalink
feat http: add Restart HTTP handler
Browse files Browse the repository at this point in the history
commit_hash:6fbd19ef34d6ecfb2675580d139306e75d6bdba9
  • Loading branch information
segoon committed Nov 8, 2024
1 parent 816c111 commit 90eddf7
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@
"core/functional_tests/basic_chaos/tests-nonchaos/metrics/test_has_reopening_error_metric.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests-nonchaos/metrics/test_has_reopening_error_metric.py",
"core/functional_tests/basic_chaos/tests-nonchaos/middlewares/test_testsuite_middleware.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests-nonchaos/middlewares/test_testsuite_middleware.py",
"core/functional_tests/basic_chaos/tests-nonchaos/network/test_interfaces.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests-nonchaos/network/test_interfaces.py",
"core/functional_tests/basic_chaos/tests-restart/conftest.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests-restart/conftest.py",
"core/functional_tests/basic_chaos/tests-restart/test_restart.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests-restart/test_restart.py",
"core/functional_tests/basic_chaos/tests/conftest.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests/conftest.py",
"core/functional_tests/basic_chaos/tests/httpclient/conftest.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests/httpclient/conftest.py",
"core/functional_tests/basic_chaos/tests/httpclient/test_httpclient.py":"taxi/uservices/userver/core/functional_tests/basic_chaos/tests/httpclient/test_httpclient.py",
Expand Down Expand Up @@ -799,6 +801,7 @@
"core/include/userver/server/handlers/log_level.hpp":"taxi/uservices/userver/core/include/userver/server/handlers/log_level.hpp",
"core/include/userver/server/handlers/on_log_rotate.hpp":"taxi/uservices/userver/core/include/userver/server/handlers/on_log_rotate.hpp",
"core/include/userver/server/handlers/ping.hpp":"taxi/uservices/userver/core/include/userver/server/handlers/ping.hpp",
"core/include/userver/server/handlers/restart.hpp":"taxi/uservices/userver/core/include/userver/server/handlers/restart.hpp",
"core/include/userver/server/handlers/server_monitor.hpp":"taxi/uservices/userver/core/include/userver/server/handlers/server_monitor.hpp",
"core/include/userver/server/handlers/tests_control.hpp":"taxi/uservices/userver/core/include/userver/server/handlers/tests_control.hpp",
"core/include/userver/server/http/form_data_arg.hpp":"taxi/uservices/userver/core/include/userver/server/http/form_data_arg.hpp",
Expand Down Expand Up @@ -1468,6 +1471,7 @@
"core/src/server/handlers/log_level.cpp":"taxi/uservices/userver/core/src/server/handlers/log_level.cpp",
"core/src/server/handlers/on_log_rotate.cpp":"taxi/uservices/userver/core/src/server/handlers/on_log_rotate.cpp",
"core/src/server/handlers/ping.cpp":"taxi/uservices/userver/core/src/server/handlers/ping.cpp",
"core/src/server/handlers/restart.cpp":"taxi/uservices/userver/core/src/server/handlers/restart.cpp",
"core/src/server/handlers/server_monitor.cpp":"taxi/uservices/userver/core/src/server/handlers/server_monitor.cpp",
"core/src/server/handlers/tests_control.cpp":"taxi/uservices/userver/core/src/server/handlers/tests_control.cpp",
"core/src/server/http/create_parser_test.hpp":"taxi/uservices/userver/core/src/server/http/create_parser_test.hpp",
Expand Down
2 changes: 2 additions & 0 deletions core/functional_tests/basic_chaos/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <userver/dynamic_config/updater/component.hpp>
#include <userver/server/handlers/on_log_rotate.hpp>
#include <userver/server/handlers/ping.hpp>
#include <userver/server/handlers/restart.hpp>
#include <userver/server/handlers/server_monitor.hpp>
#include <userver/server/handlers/tests_control.hpp>
#include <userver/utest/using_namespace_userver.hpp>
Expand All @@ -32,6 +33,7 @@ int main(int argc, char* argv[]) {
.Append<server::handlers::TestsControl>()
.Append<server::handlers::ServerMonitor>()
.Append<server::handlers::Ping>()
.Append<server::handlers::Restart>()
.Append<clients::dns::Component>()
.Append<alerts::Handler>()
.Append<components::DynamicConfigClient>()
Expand Down
5 changes: 5 additions & 0 deletions core/functional_tests/basic_chaos/static_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ components_manager:
throttling_enabled: false
url_trailing_slash: strict-match

handler-restart:
path: /restart
method: GET
task_processor: main-task-processor

task_processors:
main-task-processor:
worker_threads: 4
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest_plugins = ['pytest_userver.plugins.core', 'pytest_userver.plugins']
26 changes: 26 additions & 0 deletions core/functional_tests/basic_chaos/tests-restart/test_restart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import asyncio
import datetime


async def wait_for_daemon_stop(_global_daemon_store):
deadline = datetime.datetime.now() + datetime.timedelta(seconds=10)
while (
datetime.datetime.now() < deadline
and _global_daemon_store.has_running_daemons()
):
await asyncio.sleep(0.05)

assert (
not _global_daemon_store.has_running_daemons()
), 'Daemon has not stopped'
await _global_daemon_store.aclose()


async def test_restart(monitor_client, service_client, _global_daemon_store):
response = await monitor_client.get('/restart', params={'delay': '1'})
assert response.status == 200

response = await service_client.get('/ping')
assert response.status == 500

wait_for_daemon_stop(_global_daemon_store)
4 changes: 4 additions & 0 deletions core/include/userver/components/run.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ void RunOnce(
/// @see utils::DaemonMain
void RunOnce(const InMemoryConfig& config, const ComponentList& component_list);

/// Requests stop of the component system.
/// The service will be eventually stopped.
void RequestStop();

namespace impl {

// Composes a single static config schema from all components.
Expand Down
46 changes: 46 additions & 0 deletions core/include/userver/server/handlers/restart.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

/// @file userver/server/handlers/restart.hpp
/// @brief @copybrief server::handlers::Restart

#include <atomic>

#include <userver/server/handlers/http_handler_base.hpp>

USERVER_NAMESPACE_BEGIN

namespace server::handlers {

// clang-format off

/// @ingroup userver_components userver_http_handlers
///
/// @brief Handler that stops the service. It is expected that an external system
/// (e.g. systemd or supervisord) restarts the service afterwards.
///
/// The handler uses monitor port.
///
/// The component has no service configuration except the
/// @ref userver_http_handlers "common handler options".

// clang-format on

class Restart final : public HttpHandlerBase {
public:
Restart(const components::ComponentConfig&, const components::ComponentContext&);

/// @ingroup userver_component_names
/// @brief The default name of server::handlers::Restart
static constexpr std::string_view kName = "handler-restart";

std::string HandleRequestThrow(const http::HttpRequest&, request::RequestContext&) const override;

components::ComponentHealth GetComponentHealth() const override;

private:
mutable std::atomic<components::ComponentHealth> health_;
};

} // namespace server::handlers

USERVER_NAMESPACE_END
2 changes: 2 additions & 0 deletions core/src/components/run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ void RunOnce(const InMemoryConfig& config, const ComponentList& component_list)
DoRun(config, {}, {}, component_list, RunMode::kOnce);
}

void RequestStop() { kill(getpid(), SIGTERM); }

namespace impl {

std::string GetStaticConfigSchema(const ComponentList& component_list) {
Expand Down
40 changes: 40 additions & 0 deletions core/src/server/handlers/restart.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <userver/server/handlers/restart.hpp>

#include <userver/components/run.hpp>
#include <userver/engine/sleep.hpp>
#include <userver/utils/async.hpp>
#include <userver/utils/from_string.hpp>

USERVER_NAMESPACE_BEGIN

namespace server::handlers {

namespace {
constexpr std::string_view kDelay = "delay";
constexpr std::chrono::seconds kDelayDefault{20};
} // namespace

Restart::Restart(const components::ComponentConfig& config, const components::ComponentContext& context)
: HttpHandlerBase(config, context, true), health_{components::ComponentHealth::kOk} {}

std::string Restart::HandleRequestThrow(const http::HttpRequest& request, request::RequestContext&) const {
auto delay = kDelayDefault;
if (request.HasArg(kDelay)) {
delay = std::chrono::seconds(utils::FromString<int>(request.GetArg(kDelay)));
}

health_ = components::ComponentHealth::kFatal;
engine::CriticalAsyncNoSpan([delay] {
engine::InterruptibleSleepFor(std::chrono::seconds(delay));
if (engine::current_task::ShouldCancel()) return;
components::RequestStop();
}).Detach();

return "OK";
}

components::ComponentHealth Restart::GetComponentHealth() const { return health_; }

} // namespace server::handlers

USERVER_NAMESPACE_END

0 comments on commit 90eddf7

Please sign in to comment.