acl_master: when starting services remotely, users can wait the result of the services' starting status or not.

This commit is contained in:
zhengshuxin 2017-10-27 00:00:41 +08:00
parent 0060ea9487
commit bc4f60a2d3
18 changed files with 409 additions and 157 deletions

View File

@ -1,4 +1,7 @@
9) 2017.10.26
9.1) feature: when starting one or more services remotely, sync or async can be used.
8) 2017.9.22
8.1) workaround: restructure the manage module of acl_master.

View File

@ -1438,6 +1438,11 @@ namespace acl
else
$node.add_text("cmd", acl::get_value($obj.cmd));
if (check_nullptr($obj.timeout))
$node.add_null("timeout");
else
$node.add_number("timeout", acl::get_value($obj.timeout));
if (check_nullptr($obj.data))
$node.add_null("data");
else
@ -1464,12 +1469,16 @@ namespace acl
std::pair<bool,std::string> gson(acl::json_node &$node, start_req_t &$obj)
{
acl::json_node *cmd = $node["cmd"];
acl::json_node *timeout = $node["timeout"];
acl::json_node *data = $node["data"];
std::pair<bool, std::string> $result;
if(!cmd ||!($result = gson(*cmd, &$obj.cmd), $result.first))
return std::make_pair(false, "required [start_req_t.cmd] failed:{"+$result.second+"}");
if(timeout)
gson(*timeout, &$obj.timeout);
if(!data ||!data->get_obj()||!($result = gson(*data->get_obj(), &$obj.data), $result.first))
return std::make_pair(false, "required [start_req_t.data] failed:{"+$result.second+"}");
@ -1504,6 +1513,26 @@ namespace acl
else
$node.add_number("status", acl::get_value($obj.status));
if (check_nullptr($obj.proc_count))
$node.add_null("proc_count");
else
$node.add_number("proc_count", acl::get_value($obj.proc_count));
if (check_nullptr($obj.proc_signaled))
$node.add_null("proc_signaled");
else
$node.add_number("proc_signaled", acl::get_value($obj.proc_signaled));
if (check_nullptr($obj.proc_ok))
$node.add_null("proc_ok");
else
$node.add_number("proc_ok", acl::get_value($obj.proc_ok));
if (check_nullptr($obj.proc_err))
$node.add_null("proc_err");
else
$node.add_number("proc_err", acl::get_value($obj.proc_err));
if (check_nullptr($obj.name))
$node.add_null("name");
else
@ -1535,6 +1564,10 @@ namespace acl
std::pair<bool,std::string> gson(acl::json_node &$node, start_res_data_t &$obj)
{
acl::json_node *status = $node["status"];
acl::json_node *proc_count = $node["proc_count"];
acl::json_node *proc_signaled = $node["proc_signaled"];
acl::json_node *proc_ok = $node["proc_ok"];
acl::json_node *proc_err = $node["proc_err"];
acl::json_node *name = $node["name"];
acl::json_node *path = $node["path"];
std::pair<bool, std::string> $result;
@ -1542,6 +1575,18 @@ namespace acl
if(!status ||!($result = gson(*status, &$obj.status), $result.first))
return std::make_pair(false, "required [start_res_data_t.status] failed:{"+$result.second+"}");
if(!proc_count ||!($result = gson(*proc_count, &$obj.proc_count), $result.first))
return std::make_pair(false, "required [start_res_data_t.proc_count] failed:{"+$result.second+"}");
if(!proc_signaled ||!($result = gson(*proc_signaled, &$obj.proc_signaled), $result.first))
return std::make_pair(false, "required [start_res_data_t.proc_signaled] failed:{"+$result.second+"}");
if(!proc_ok ||!($result = gson(*proc_ok, &$obj.proc_ok), $result.first))
return std::make_pair(false, "required [start_res_data_t.proc_ok] failed:{"+$result.second+"}");
if(!proc_err ||!($result = gson(*proc_err, &$obj.proc_err), $result.first))
return std::make_pair(false, "required [start_res_data_t.proc_err] failed:{"+$result.second+"}");
if(!name ||!($result = gson(*name, &$obj.name), $result.first))
return std::make_pair(false, "required [start_res_data_t.name] failed:{"+$result.second+"}");

View File

@ -95,13 +95,30 @@ struct start_req_data_t
struct start_req_t : req_t
{
// Gson@optional
long long timeout;
std::vector<start_req_data_t> data;
start_req_t(void) : timeout(-1) {}
};
struct start_res_data_t
{
start_res_data_t(void)
{
status = 0;
proc_count = 0;
proc_signaled = 0;
proc_ok = 0;
proc_err = 0;
}
int status;
int proc_count;
int proc_signaled;
int proc_ok;
int proc_err;
acl::string name;
// Gson@optional
acl::string path;
@ -216,6 +233,7 @@ struct reload_res_data_t
int proc_signaled;
int proc_ok;
int proc_err;
acl::string path;
};

View File

@ -95,13 +95,30 @@ struct start_req_data_t
struct start_req_t : req_t
{
// Gson@optional
long long timeout;
std::vector<start_req_data_t> data;
start_req_t(void) : timeout(-1) {}
};
struct start_res_data_t
{
start_res_data_t(void)
{
status = 0;
proc_count = 0;
proc_signaled = 0;
proc_ok = 0;
proc_err = 0;
}
int status;
int proc_count;
int proc_signaled;
int proc_ok;
int proc_err;
acl::string name;
// Gson@optional
acl::string path;
@ -216,6 +233,7 @@ struct reload_res_data_t
int proc_signaled;
int proc_ok;
int proc_err;
acl::string path;
};

View File

@ -15,10 +15,9 @@
#include "master/master_params.h"
#include "master/master_api.h"
#include "manage/http_client.h"
#include "type_defs.h"
#include "service_reload.h"
#define STATUS_TIMEOUT 503
service_reload::service_reload(http_client& client)
: client_(client)
, proc_count_(0)
@ -29,6 +28,65 @@ service_reload::service_reload(http_client& client)
timeout_ = (long long) acl_var_master_reload_timeo * 1000;
}
bool service_reload::run(acl::json& json)
{
reload_req_t req;
//logger(">>>%s<<<", json_.to_string().c_str());
if (deserialize<reload_req_t>(json, req) == false) {
reload_res_t res;
res.status = 400;
res.msg = "invalid json";
client_.reply<reload_res_t>(res.status, res);
delete this;
return false;
}
return handle(req);
}
bool service_reload::handle(const reload_req_t& req)
{
bool waiting;
if (req.timeout > 0) {
timeout_ = req.timeout * 1000;
waiting = true;
} else {
timeout_ = 0;
waiting = false;
}
// logger(">>>>timeout_: %lld, %lld<<<", timeout_, req.timeout);
if (waiting)
acl_event_request_timer(acl_var_master_global_event,
service_reload_timer, this, timeout_, 0);
for (std::vector<reload_req_data_t>::const_iterator
cit = req.data.begin(); cit != req.data.end(); ++cit) {
reload_res_data_t data;
if (reload_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)
reload_finish();
return true;
}
bool service_reload::reload_one(const char* path, reload_res_data_t& data,
bool waiting)
{
@ -51,82 +109,17 @@ bool service_reload::reload_one(const char* path, reload_res_data_t& data,
return true;
}
bool service_reload::run(acl::json& json)
{
reload_req_t req;
reload_res_t res;
res.status = 200;
res.msg = "ok";
//logger(">>>%s<<<", json_.to_string().c_str());
if (deserialize<reload_req_t>(json, req) == false) {
res.status = 400;
res.msg = "invalid json";
client_.reply<reload_res_t>(res.status, res);
return false;
}
return handle(req);
}
bool service_reload::handle(const reload_req_t& req)
{
size_t n = 0;
bool waiting;
if (req.timeout > 0) {
timeout_ = req.timeout * 1000;
waiting = true;
} else {
timeout_ = 0;
waiting = false;
}
// logger(">>>>timeout_: %lld, %lld<<<", timeout_, req.timeout);
if (waiting)
acl_event_request_timer(acl_var_master_global_event,
service_reload_timer, this, timeout_, 0);
for (std::vector<reload_req_data_t>::const_iterator
cit = req.data.begin(); cit != req.data.end(); ++cit) {
reload_res_data_t data;
if (reload_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);
}
n++;
} else
res_.data.push_back(data);
}
if (!waiting)
reload_finish();
return true;
}
void service_reload::service_reload_timer(int, ACL_EVENT*, void* ctx)
{
service_reload* reload = (service_reload *) ctx;
reload->timeout_callback();
}
void service_reload::service_reload_callback(ACL_MASTER_PROC* proc, int sig,
void service_reload::service_reload_callback(ACL_MASTER_PROC* proc,
int status, void* ctx)
{
service_reload* reload = (service_reload *) ctx;
if (sig != SIGHUP)
logger_error("not SIGHUP, invalid signum=%d", sig);
else
reload->reload_callback(proc, status);
service_reload* service = (service_reload *) ctx;
service->reload_callback(proc, status);
}
void service_reload::reload_callback(ACL_MASTER_PROC* proc, int status)
@ -175,15 +168,6 @@ void service_reload::timeout_callback(void)
}
void service_reload::reload_finish(void)
{
clean_all();
client_.reply<reload_res_t>(res_.status, res_);
client_.on_finish();
delete this;
}
void service_reload::clean_all(void)
{
acl_event_cancel_timer(acl_var_master_global_event,
service_reload_timer, this);
@ -191,6 +175,11 @@ void service_reload::clean_all(void)
for (std::map<acl::string, reload_res_data_t>::iterator
it = servers_.begin(); it != servers_.end(); ++it) {
acl_master_reload_clean(it->first.c_str());
acl_master_callback_clean(it->first.c_str());
}
client_.reply<reload_res_t>(res_.status, res_);
client_.on_finish();
delete this;
}

View File

@ -42,12 +42,11 @@ private:
bool reload_one(const char* path, reload_res_data_t& data,
bool sync_wait);
void timeout_callback(void);
void reload_callback(ACL_MASTER_PROC* proc, int status);
void timeout_callback(void);
void reload_finish(void);
void clean_all(void);
static void service_reload_timer(int, ACL_EVENT* event, void* ctx);
static void service_reload_callback(ACL_MASTER_PROC* proc, int sig,
static void service_reload_callback(ACL_MASTER_PROC* proc,
int status, void* ctx);
};

View File

@ -40,7 +40,8 @@ bool service_restart::handle(const restart_req_t& req, restart_res_t& res)
cit = req.data.begin(); cit != req.data.end(); ++cit) {
const char* path = (*cit).path.c_str();
if ((serv = acl_master_restart(path)) == NULL) {
serv = acl_master_restart(path, NULL, NULL, NULL, NULL);
if (serv == NULL) {
data.status = 500;
data.path = path;
} else {

View File

@ -11,60 +11,173 @@
*/
#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;
start_res_t res;
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, res);
return handle(req);
}
bool service_start::handle(const start_req_t& req, start_res_t& res)
bool service_start::handle(const start_req_t& req)
{
start_res_data_t data;
const ACL_MASTER_SERV* serv;
size_t n = 0;
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<start_req_data_t>::const_iterator
cit = req.data.begin(); cit != req.data.end(); ++cit) {
const char* path = (*cit).path.c_str();
if ((serv = acl_master_start(path)) == NULL) {
data.status = 500;
data.path = path;
} else {
data.status = 200;
data.name = serv->name;
data.path = serv->path;
n++;
}
start_res_data_t data;
res.data.push_back(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 (n == req.data.size()) {
res.status = 200;
res.msg = "ok";
} else {
res.status = 500;
res.msg = "error";
logger_error("not all service have been started!, n=%d, %d",
(int) n, (int) req.data.size());
}
client_.reply<start_res_t>(res.status, res);
client_.on_finish();
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<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;
}

View File

@ -11,6 +11,7 @@
*/
#pragma once
#include "master/master.h"
struct start_req_t;
struct start_res_t;
@ -19,13 +20,31 @@ class http_client;
class service_start
{
public:
service_start(http_client& client) : client_(client) {}
~service_start(void) {}
service_start(http_client& client);
bool run(acl::json& json);
private:
http_client& client_;
~service_start(void) {}
bool handle(const start_req_t& req, start_res_t& res);
bool handle(const start_req_t& req);
private:
http_client& client_;
start_res_t res_;
long long timeout_;
int proc_count_;
int proc_signaled_;
size_t servers_finished_;
std::map<acl::string, start_res_data_t> servers_;
bool start_one(const char* path, start_res_data_t& data, bool status);
void start_callback(ACL_MASTER_PROC* proc, int status);
void timeout_callback(void);
void start_finish(void);
static void service_start_timer(int, ACL_EVENT* event, void* ctx);
static void service_start_callback(ACL_MASTER_PROC* proc,
int status, void *ctx);
};

View File

@ -224,8 +224,8 @@ bool http_client::handle_stop(void)
bool http_client::handle_start(void)
{
service_start service(*this);
return service.run(json_);
service_start* service = new service_start(*this);
return service->run(json_);
}
bool http_client::handle_restart(void)
@ -237,8 +237,7 @@ bool http_client::handle_restart(void)
bool http_client::handle_reload(void)
{
service_reload* service = new service_reload(*this);
service->run(json_);
return true;
return service->run(json_);
}
void http_client::on_finish(void)

View File

@ -5,6 +5,9 @@
extern "C" {
#endif
typedef struct ACL_MASTER_PROC ACL_MASTER_PROC;
typedef void (*STATUS_CALLBACK)(ACL_MASTER_PROC*, int, void*);
typedef struct ACL_MASTER_NV {
char *name;
char *value;
@ -52,6 +55,9 @@ typedef struct ACL_MASTER_SERV {
ACL_VSTREAM *status_reader; /* status stream */
ACL_RING children; /* linkage of children */
struct ACL_MASTER_SERV *next; /* linkage of serv */
STATUS_CALLBACK callback;
void *ctx;
} ACL_MASTER_SERV;
#define ACL_MASTER_CHILDREN_SIZE(s) acl_ring_size(&s->children)
@ -97,8 +103,6 @@ typedef struct ACL_MASTER_SERV {
* Structure of child process.
*/
typedef int ACL_MASTER_PID; /* pid is key into binhash table */
typedef struct ACL_MASTER_PROC ACL_MASTER_PROC;
typedef void (*SIGNAL_CALLBACK)(ACL_MASTER_PROC*, int, int, void*);
typedef struct ACL_MASTER_PROC {
ACL_RING me; /* linked in serv's children */
@ -108,8 +112,8 @@ typedef struct ACL_MASTER_PROC {
int use_count; /* number of service requests */
ACL_MASTER_PID pid; /* child process id */
ACL_MASTER_SERV *serv; /* parent linkage */
SIGNAL_CALLBACK signal_callback;
void *signal_ctx;
STATUS_CALLBACK callback;
void *ctx;
} ACL_MASTER_PROC;
/*
@ -197,9 +201,9 @@ extern void acl_master_reap_child(void);
extern void acl_master_kill_children(ACL_MASTER_SERV *);
extern void acl_master_delete_all_children(void);
extern void acl_master_signal_children(ACL_MASTER_SERV *serv, int signum,
int *nchildren, int *nsignaled, SIGNAL_CALLBACK, void*);
int *nchildren, int *nsignaled);
extern void acl_master_sighup_children(ACL_MASTER_SERV *serv, int *nchildren,
int *nsignaled, SIGNAL_CALLBACK callback, void *ctx);
int *nsignaled);
/*
* master_warning.c

View File

@ -24,6 +24,17 @@
#define SAME !strcmp
static void setup_callback(const char *service, ACL_MASTER_SERV *serv,
STATUS_CALLBACK callback, void *ctx)
{
if (serv->callback == NULL) {
serv->callback = callback;
serv->ctx = ctx;
} else if (callback != NULL)
acl_msg_warn("%s(%d), %s: another callback is set!",
__FILE__, __LINE__, service);
}
ACL_MASTER_SERV *acl_master_lookup(const char *path)
{
ACL_MASTER_SERV *entry = acl_master_ent_load(path), *serv;
@ -39,7 +50,8 @@ ACL_MASTER_SERV *acl_master_lookup(const char *path)
return serv;
}
ACL_MASTER_SERV *acl_master_start(const char *path)
ACL_MASTER_SERV *acl_master_start(const char *path, int *nchilden,
int *nsignaled, STATUS_CALLBACK callback, void *ctx)
{
ACL_MASTER_SERV *entry = acl_master_ent_load(path), *serv;
@ -58,21 +70,31 @@ ACL_MASTER_SERV *acl_master_start(const char *path)
return NULL;
}
if (nchilden)
*nchilden = entry->prefork_proc;
if (nsignaled)
*nsignaled = entry->prefork_proc;
setup_callback(__FUNCTION__, serv, callback, ctx);
entry->next = acl_var_master_head;
acl_var_master_head = entry;
acl_master_service_start(entry);
return entry;
}
ACL_MASTER_SERV *acl_master_restart(const char *path)
ACL_MASTER_SERV *acl_master_restart(const char *path, int *nchilden,
int *nsignaled, STATUS_CALLBACK callback, void *ctx)
{
ACL_MASTER_SERV *serv = acl_master_lookup(path);
if (serv == NULL)
return acl_master_start(path);
if (serv != NULL) {
acl_master_service_restart(serv);
return serv;
}
acl_master_service_restart(serv);
return serv;
return acl_master_start(path, nchilden, nsignaled, callback, ctx);
}
/* kill processes of service according the master_service name in configure */
@ -134,7 +156,7 @@ int acl_master_stop(const char *path)
}
int acl_master_reload(const char *path, int *nchilden, int *nsignaled,
SIGNAL_CALLBACK callback, void *ctx)
STATUS_CALLBACK callback, void *ctx)
{
ACL_MASTER_SERV *serv = acl_master_lookup(path);
@ -144,11 +166,13 @@ int acl_master_reload(const char *path, int *nchilden, int *nsignaled,
return -1;
}
acl_master_sighup_children(serv, nchilden, nsignaled, callback, ctx);
setup_callback(__FUNCTION__, serv, callback, ctx);
acl_master_sighup_children(serv, nchilden, nsignaled);
return 0;
}
void acl_master_reload_clean(const char *path)
void acl_master_callback_clean(const char *path)
{
ACL_MASTER_SERV *serv = acl_master_lookup(path);
if (serv == NULL)
@ -159,7 +183,10 @@ void acl_master_reload_clean(const char *path)
acl_ring_foreach(iter, &serv->children) {
proc = acl_ring_to_appl(iter.ptr, ACL_MASTER_PROC, me);
acl_assert(proc);
proc->signal_callback = NULL;
proc->signal_ctx = NULL;
proc->callback = NULL;
proc->ctx = NULL;
}
serv->callback = NULL;
serv->ctx = NULL;
}

View File

@ -20,13 +20,15 @@ extern "C" {
#include "master.h"
extern ACL_MASTER_SERV *acl_master_lookup(const char *path);
extern ACL_MASTER_SERV *acl_master_start(const char *path);
extern ACL_MASTER_SERV *acl_master_restart(const char *path);
extern ACL_MASTER_SERV *acl_master_start(const char *path, int *nchilden,
int *nsignaled, STATUS_CALLBACK callback, void *ctx);
extern ACL_MASTER_SERV *acl_master_restart(const char *path, int *nchilden,
int *nsignaled, STATUS_CALLBACK callback, void *ctx);
extern int acl_master_kill(const char *path);
extern int acl_master_stop(const char *path);
extern int acl_master_reload(const char *path, int *nchildren, int *nsignaled,
SIGNAL_CALLBACK callback, void *ctx);
extern void acl_master_reload_clean(const char *path);
STATUS_CALLBACK callback, void *ctx);
extern void acl_master_callback_clean(const char *path);
#ifdef __cplusplus

View File

@ -15,6 +15,7 @@ int acl_var_master_in_flow_delay;
int acl_var_master_delay_sec;
int acl_var_master_delay_usec;
int acl_var_master_reload_timeo;
int acl_var_master_start_timeo;
static ACL_CONFIG_INT_TABLE int_tab[] = {
{ ACL_VAR_MASTER_PROC_LIMIT, ACL_DEF_MASTER_PROC_LIMIT,
@ -33,6 +34,8 @@ static ACL_CONFIG_INT_TABLE int_tab[] = {
&acl_var_master_delay_usec, 0, 0 },
{ ACL_VAR_MASTER_RELOAD_TIMEO, ACL_DEF_MASTER_RELOAD_TIMEO,
&acl_var_master_reload_timeo, 0, 0 },
{ ACL_VAR_MASTER_START_TIMEO, ACL_DEF_MASTER_START_TIMEO,
&acl_var_master_start_timeo, 0, 0 },
{ 0, 0, 0, 0, 0 },
};

View File

@ -109,6 +109,10 @@ extern char *acl_var_master_manage_addr;
#define ACL_DEF_MASTER_RELOAD_TIMEO 5000
extern int acl_var_master_reload_timeo;
#define ACL_VAR_MASTER_START_TIMEO "start_timeout"
#define ACL_DEF_MASTER_START_TIMEO 5000
extern int acl_var_master_start_timeo;
/* every service's configure entry is different*/
#define ACL_VAR_MASTER_SERV_DISABLE "master_disable"

View File

@ -240,8 +240,8 @@ void acl_master_spawn(ACL_MASTER_SERV *serv)
proc->avail = 0;
proc->start = (long) time(NULL);
proc->use_count = 0;
proc->signal_callback = NULL;
proc->signal_ctx = NULL;
proc->callback = NULL;
proc->ctx = NULL;
acl_binhash_enter(acl_var_master_child_table,
(char *) &pid, sizeof(pid), (char *) proc);
@ -463,7 +463,7 @@ void acl_master_delete_all_children(void)
}
void acl_master_signal_children(ACL_MASTER_SERV *serv, int signum,
int *nchildren, int *nsignaled, SIGNAL_CALLBACK callback, void *ctx)
int *nchildren, int *nsignaled)
{
const char *myname = "acl_master_signal_children";
ACL_RING_ITER iter;
@ -475,16 +475,15 @@ void acl_master_signal_children(ACL_MASTER_SERV *serv, int signum,
acl_assert(proc);
// setup callback first
proc->signal_callback = callback;
proc->signal_ctx = ctx;
proc->callback = serv->callback;
proc->ctx = serv->ctx;
if (nchildren)
(*nchildren)++;
if (kill(proc->pid, signum) < 0)
acl_msg_warn("%s: kill child %d, path %s error %s",
myname, proc->pid, serv->path, strerror(errno));
else
{
else {
if (nsignaled)
(*nsignaled)++;
n++;
@ -497,8 +496,7 @@ void acl_master_signal_children(ACL_MASTER_SERV *serv, int signum,
}
void acl_master_sighup_children(ACL_MASTER_SERV *serv, int *nchildren,
int *nsignaled, SIGNAL_CALLBACK callback, void *ctx)
int *nsignaled)
{
acl_master_signal_children(serv, SIGHUP, nchildren, nsignaled,
callback, ctx);
acl_master_signal_children(serv, SIGHUP, nchildren, nsignaled);
}

View File

@ -125,11 +125,18 @@ static void master_status_event(int type, ACL_EVENT *event acl_unused,
break;
case ACL_MASTER_STAT_SIGHUP_OK:
case ACL_MASTER_STAT_SIGHUP_ERR:
if (proc->signal_callback) {
proc->signal_callback(proc, SIGHUP,
stat_buf.status, proc->signal_ctx);
proc->signal_callback = NULL;
proc->signal_ctx = NULL;
if (proc->callback) {
proc->callback(proc, stat_buf.status, proc->ctx);
proc->callback = NULL;
proc->ctx = NULL;
}
break;
case ACL_MASTER_STAT_START_OK:
case ACL_MASTER_STAT_START_ERR:
if (proc->callback) {
proc->callback(proc, stat_buf.status, proc->ctx);
proc->callback = NULL;
proc->ctx = NULL;
}
break;
default:

View File

@ -49,6 +49,9 @@ typedef struct ACL_MASTER_STATUS {
#define ACL_MASTER_STAT_AVAIL 1 /* this process is idle */
#define ACL_MASTER_STAT_SIGHUP_OK 2
#define ACL_MASTER_STAT_SIGHUP_ERR 3
#define ACL_MASTER_STAT_START_OK 4
#define ACL_MASTER_STAT_START_ERR 5
int acl_master_notify(int, unsigned, int); /* encapsulate status msg */
/*