blob: fa9bff1542fa79fa8f7df290f364f5d549a9a3b9 [file] [log] [blame]
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Microsoft Corporation
*
* -=- Robust Distributed System Nucleus (rDSN) -=-
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "runtime/tool_api.h"
#include <algorithm>
#include <functional>
#include <map>
#include <memory>
#include <type_traits>
#include <utility>
#include "runtime/global_config.h"
#include "runtime/rpc/message_parser_manager.h"
#include "runtime/service_engine.h"
#include "runtime/task/task.h"
#include "runtime/task/task_code.h"
#include "utils/error_code.h"
#include "utils/factory_store.h"
#include "utils/fmt_logging.h"
#include "utils/singleton_store.h"
#include "utils/sys_exit_hook.h"
#include "utils/threadpool_code.h"
namespace dsn {
DEFINE_TASK_CODE(LPC_CONTROL_SERVICE_APP, TASK_PRIORITY_HIGH, THREAD_POOL_DEFAULT)
class service_control_task : public task
{
public:
service_control_task(service_node *node, bool start, bool cleanup = false)
: task(LPC_CONTROL_SERVICE_APP, 0, node), _node(node), _start(start), _cleanup(cleanup)
{
}
void exec()
{
auto &sp = _node->spec();
if (_start) {
error_code err;
err = _node->start_app();
CHECK_EQ_MSG(err, ERR_OK, "start app failed");
} else {
LOG_INFO("stop app result({})", _node->stop_app(_cleanup));
}
}
private:
service_node *_node;
bool _start; // false for stop
bool _cleanup; // for stop
};
namespace tools {
tool_base::tool_base(const char *name) { _name = name; }
toollet::toollet(const char *name) : tool_base(name) {}
tool_app::tool_app(const char *name) : tool_base(name) {}
void tool_app::start_all_apps()
{
const auto &apps = service_engine::instance().get_all_nodes();
for (const auto &kv : apps) {
task *t = new service_control_task(kv.second.get(), true);
t->set_delay(1000 * kv.second.get()->spec().delay_seconds);
t->enqueue();
}
}
void tool_app::stop_all_apps(bool cleanup)
{
const auto &apps = service_engine::instance().get_all_nodes();
for (const auto &kv : apps) {
task *t = new service_control_task(kv.second.get(), false, cleanup);
t->enqueue();
}
}
const service_spec &tool_app::get_service_spec() { return service_engine::instance().spec(); }
const service_spec &spec() { return service_engine::instance().spec(); }
const char *get_service_node_name(service_node *node) { return node->full_name(); }
join_point<void> sys_init_before_app_created("system.init.1");
join_point<void> sys_init_after_app_created("system.init.2");
join_point<void, sys_exit_type> sys_exit("system.exit");
namespace internal_use_only {
bool register_toollet(const char *name, toollet::factory f, ::dsn::provider_type type)
{
return dsn::utils::factory_store<toollet>::register_factory(name, f, type);
}
bool register_tool(const char *name, tool_app::factory f, ::dsn::provider_type type)
{
return dsn::utils::factory_store<tool_app>::register_factory(name, f, type);
}
bool register_component_provider(const char *name,
timer_service::factory f,
::dsn::provider_type type)
{
return dsn::utils::factory_store<timer_service>::register_factory(name, f, type);
}
bool register_component_provider(const char *name, task_queue::factory f, ::dsn::provider_type type)
{
return dsn::utils::factory_store<task_queue>::register_factory(name, f, type);
}
bool register_component_provider(const char *name,
task_worker::factory f,
::dsn::provider_type type)
{
return dsn::utils::factory_store<task_worker>::register_factory(name, f, type);
}
bool register_component_provider(const char *name, network::factory f, ::dsn::provider_type type)
{
return dsn::utils::factory_store<network>::register_factory(name, f, type);
}
bool register_component_provider(const char *name,
env_provider::factory f,
::dsn::provider_type type)
{
return dsn::utils::factory_store<env_provider>::register_factory(name, f, type);
}
bool register_component_provider(network_header_format fmt,
const std::vector<const char *> &signatures,
message_parser::factory f,
size_t sz)
{
message_parser_manager::instance().register_factory(fmt, signatures, f, sz);
return true;
}
toollet *get_toollet(const char *name, ::dsn::provider_type type)
{
toollet *tlt = nullptr;
if (utils::singleton_store<std::string, toollet *>::instance().get(name, tlt))
return tlt;
else {
tlt = utils::factory_store<toollet>::create(name, type, name);
utils::singleton_store<std::string, toollet *>::instance().put(name, tlt);
return tlt;
}
}
} // namespace internal_use_only
} // namespace tools
} // namespace dsn