/** * 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" #include "master/master_api.h" #include "manage/http_client.h" #include "type_defs.h" #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; if (deserialize(json, req) == false) { start_res_t res; res.status = 400; res.msg = "invalid json"; client_.reply(res.status, res); delete this; return false; } return handle(req); } bool service_start::handle(const start_req_t& req) { 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); for (std::vector::const_iterator 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); } 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; } else { data.status = timeout_ > 0 ? STATUS_TIMEOUT : 200; data.name = serv->name; return true; } } 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(); } void service_start::start_callback(ACL_MASTER_PROC* proc, int status) { std::map::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::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::iterator it = servers_.begin(); it != servers_.end(); ++it) { acl_master_callback_clean(it->first.c_str()); } client_.reply(res_.status, res_); client_.on_finish(); delete this; }