acl/app/master/daemon/manage/action/service_start.cpp

184 lines
3.9 KiB
C++
Raw Normal View History

2017-06-16 17:00:49 +08:00
/**
* Copyright (C) 2015-2018
* All rights reserved.
*
* AUTHOR(S)
* Zheng Shuxin
* E-mail: zhengshuxin@qiyi.com
*
* VERSION
* Fri 16 Jun 2017 02:00:01 PM CST
*/
#include "stdafx.h"
#include "master/master_params.h"
2017-06-16 17:00:49 +08:00
#include "master/master_api.h"
#include "manage/http_client.h"
#include "type_defs.h"
2017-06-16 17:00:49 +08:00
#include "service_start.h"
service_start::service_start(http_client& client)
: client_(client)
, proc_count_(0)
, proc_signaled_(0)
, servers_finished_(0)
{
res_.status = 200;
timeout_ = (long long) acl_var_master_start_timeo * 1000;
}
bool service_start::run(acl::json& json)
{
start_req_t req;
2017-09-24 21:10:28 +08:00
if (deserialize<start_req_t>(json, req) == false) {
start_res_t res;
res.status = 400;
res.msg = "invalid json";
client_.reply<start_res_t>(res.status, res);
delete this;
return false;
}
return handle(req);
}
bool service_start::handle(const start_req_t& req)
2017-06-16 17:00:49 +08:00
{
bool waiting;
if (req.timeout > 0) {
timeout_ = req.timeout * 1000;
waiting = true;
} else {
timeout_ = 0;
waiting = false;
}
if (waiting)
acl_event_request_timer(acl_var_master_global_event,
service_start_timer, this, timeout_, 0);
2017-06-16 17:00:49 +08:00
2017-06-27 17:11:04 +08:00
for (std::vector<start_req_data_t>::const_iterator
2017-09-24 21:10:28 +08:00
cit = req.data.begin(); cit != req.data.end(); ++cit) {
start_res_data_t data;
if (start_one((*cit).path.c_str(), data, waiting)) {
proc_count_ += data.proc_count;
proc_signaled_ += data.proc_signaled;
servers_[data.path] = data;
if (!waiting) {
data.status = 200;
res_.data.push_back(data);
}
} else
res_.data.push_back(data);
2017-06-16 17:00:49 +08:00
}
if (!waiting)
start_finish();
return true;
}
bool service_start::start_one(const char* path, start_res_data_t& data,
bool waiting)
{
data.status = STATUS_TIMEOUT;
data.path = path;
data.proc_count = 0;
data.proc_signaled = 0;
data.proc_ok = 0;
data.proc_err = 0;
const ACL_MASTER_SERV* serv = acl_master_start(path,
&data.proc_count, &data.proc_signaled,
waiting ? service_start_callback : NULL,
waiting ? this : NULL);
if (serv == NULL) {
data.status = 500;
data.proc_err++;
return false;
2017-09-24 21:10:28 +08:00
} else {
data.status = timeout_ > 0 ? STATUS_TIMEOUT : 200;
data.name = serv->name;
return true;
2017-06-16 17:00:49 +08:00
}
}
void service_start::service_start_callback(ACL_MASTER_PROC* proc,
int status, void *ctx)
{
service_start *service = (service_start *) ctx;
service->start_callback(proc, status);
}
void service_start::service_start_timer(int, ACL_EVENT*, void* ctx)
{
service_start* service = (service_start *) ctx;
service->timeout_callback();
}
2017-06-16 17:00:49 +08:00
void service_start::start_callback(ACL_MASTER_PROC* proc, int status)
{
std::map<acl::string, start_res_data_t>::iterator it =
servers_.find(proc->serv->conf);
if (it == servers_.end()) {
logger_error("not found, path=%s", proc->serv->conf);
return;
}
if (status == ACL_MASTER_STAT_START_OK)
it->second.proc_ok++;
else {
res_.status = 500;
res_.msg = "some services start failed";
it->second.proc_err++;
}
if (it->second.proc_ok + it->second.proc_err < it->second.proc_count)
return;
if (it->second.proc_err > 0)
it->second.status = 500;
else
it->second.status = 200;
res_.data.push_back(it->second);
if (++servers_finished_ == servers_.size())
start_finish();
}
void service_start::timeout_callback(void)
{
logger("start timeout reached, timeout=%lld ms", timeout_ / 1000);
for (std::map<acl::string, start_res_data_t>::iterator
it = servers_.begin(); it != servers_.end(); ++it) {
if (it->second.status == STATUS_TIMEOUT)
res_.data.push_back(it->second);
}
start_finish();
}
void service_start::start_finish(void)
{
acl_event_cancel_timer(acl_var_master_global_event,
service_start_timer, this);
for (std::map<acl::string, start_res_data_t>::iterator
it = servers_.begin(); it != servers_.end(); ++it) {
acl_master_callback_clean(it->first.c_str());
}
client_.reply<start_res_t>(res_.status, res_);
client_.on_finish();
delete this;
2017-06-16 17:00:49 +08:00
}