Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support HTTP-API for fetching reload result. v5.0.176 v6.0.71 #3779

Merged
merged 5 commits into from
Aug 30, 2023
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
@@ -1333,30 +1333,36 @@ void SrsConfig::unsubscribe(ISrsReloadHandler* handler)
}

// LCOV_EXCL_START
srs_error_t SrsConfig::reload()
srs_error_t SrsConfig::reload(SrsReloadState *pstate)
{
*pstate = SrsReloadStateInit;

srs_error_t err = srs_success;

SrsConfig conf;


*pstate = SrsReloadStateParsing;
if ((err = conf.parse_file(config_file.c_str())) != srs_success) {
return srs_error_wrap(err, "parse file");
}
srs_info("config reloader parse file success.");

// transform config to compatible with previous style of config.
*pstate = SrsReloadStateTransforming;
if ((err = srs_config_transform_vhost(conf.root)) != srs_success) {
return srs_error_wrap(err, "transform config");
}

if ((err = conf.check_config()) != srs_success) {
return srs_error_wrap(err, "check config");
}


*pstate = SrsReloadStateApplying;
if ((err = reload_conf(&conf)) != srs_success) {
return srs_error_wrap(err, "reload config");
}


*pstate = SrsReloadStateFinished;
return err;
}
// LCOV_EXCL_STOP
15 changes: 14 additions & 1 deletion trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
@@ -256,6 +256,19 @@ class SrsConfDirective
virtual srs_error_t read_token(srs_internal::SrsConfigBuffer* buffer, std::vector<std::string>& args, int& line_start, SrsDirectiveState& state);
};

// The state for reloading config.
enum SrsReloadState {
SrsReloadStateInit = 0,
// Start to parse the new config file.
SrsReloadStateParsing = 10,
// Start to transform the new config file to new version.
SrsReloadStateTransforming = 20,
// Start to apply the new config file.
SrsReloadStateApplying = 30,
// The reload is finished.
SrsReloadStateFinished = 90,
};

// The config service provider.
// For the config supports reload, so never keep the reference cross st-thread,
// that is, never save the SrsConfDirective* get by any api of config,
@@ -308,7 +321,7 @@ class SrsConfig
virtual void unsubscribe(ISrsReloadHandler* handler);
// Reload the config file.
// @remark, user can test the config before reload it.
virtual srs_error_t reload();
virtual srs_error_t reload(SrsReloadState *pstate);
private:
// Reload the vhost section of config.
virtual srs_error_t reload_vhost(SrsConfDirective* old_root);
20 changes: 17 additions & 3 deletions trunk/src/app/srs_app_http_api.cpp
Original file line number Diff line number Diff line change
@@ -863,7 +863,7 @@ srs_error_t SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
}
} else {
SrsJsonObject* data = SrsJsonAny::object();
obj->set("client", data);;
obj->set("client", data);

if ((err = client->dumps(data)) != srs_success) {
int code = srs_error_code(err);
@@ -907,6 +907,10 @@ SrsGoApiRaw::~SrsGoApiRaw()
_srs_config->unsubscribe(this);
}

extern srs_error_t _srs_reload_err;
extern SrsReloadState _srs_reload_state;
extern std::string _srs_reload_id;

srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
srs_error_t err = srs_success;
@@ -937,8 +941,8 @@ srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*

//////////////////////////////////////////////////////////////////////////
// the rpc is required.
// the allowd rpc method check.
if (rpc.empty() || rpc != "reload") {
// the allowed rpc method check.
if (rpc.empty() || (rpc != "reload" && rpc != "reload-fetch")) {
return srs_api_response_code(w, r, ERROR_SYSTEM_CONFIG_RAW);
}

@@ -950,6 +954,16 @@ srs_error_t SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*

server->on_signal(SRS_SIGNAL_RELOAD);
return srs_api_response_code(w, r, ERROR_SUCCESS);
} else if (rpc == "reload-fetch") {
SrsJsonObject* data = SrsJsonAny::object();
obj->set("data", data);

data->set("err", SrsJsonAny::integer(srs_error_code(_srs_reload_err)));
data->set("msg", SrsJsonAny::str(srs_error_summary(_srs_reload_err).c_str()));
data->set("state", SrsJsonAny::integer(_srs_reload_state));
data->set("rid", SrsJsonAny::str(_srs_reload_id.c_str()));

return srs_api_response(w, r, obj->dumps());
}

return err;
33 changes: 27 additions & 6 deletions trunk/src/app/srs_app_server.cpp
Original file line number Diff line number Diff line change
@@ -870,7 +870,9 @@ srs_error_t SrsServer::cycle()
}

// Do server main cycle.
err = do_cycle();
if ((err = do_cycle()) != srs_success) {
srs_error("server err %s", srs_error_desc(err).c_str());
}

// OK, SRS server is done.
wg_->done();
@@ -942,6 +944,10 @@ void SrsServer::on_signal(int signo)
}
}

srs_error_t _srs_reload_err;
SrsReloadState _srs_reload_state;
std::string _srs_reload_id;

srs_error_t SrsServer::do_cycle()
{
srs_error_t err = srs_success;
@@ -991,12 +997,27 @@ srs_error_t SrsServer::do_cycle()
// do reload the config.
if (signal_reload) {
signal_reload = false;
srs_info("get signal to reload the config.");

if ((err = _srs_config->reload()) != srs_success) {
return srs_error_wrap(err, "config reload");
srs_trace("starting reload config.");

SrsReloadState state = SrsReloadStateInit;
_srs_reload_state = SrsReloadStateInit; srs_freep(_srs_reload_err); _srs_reload_id = srs_random_str(7);
err = _srs_config->reload(&state);
_srs_reload_state = state; _srs_reload_err = srs_error_copy(err);
if (err != srs_success) {
// If the parsing and transformation of the configuration fail, we can tolerate it by simply
// ignoring the new configuration and continuing to use the current one. However, if the
// application of the new configuration fails, some configurations may be applied while
// others may not. For instance, the listening port may be closed when the configuration
// is set to listen on an unavailable port. In such cases, we should terminate the service.
if (state == SrsReloadStateApplying) {
return srs_error_wrap(err, "reload fatal error state=%d", state);
}

srs_warn("reload failed, state=%d, err %s", state, srs_error_desc(err).c_str());
srs_freep(err);
} else {
srs_trace("reload config success, state=%d.", state);
}
srs_trace("reload config success.");
}

srs_usleep(1 * SRS_UTIME_SECONDS);
8 changes: 8 additions & 0 deletions trunk/src/app/srs_app_threads.cpp
Original file line number Diff line number Diff line change
@@ -295,6 +295,10 @@ srs_error_t SrsCircuitBreaker::on_timer(srs_utime_t interval)
SrsCircuitBreaker* _srs_circuit_breaker = NULL;
SrsAsyncCallWorker* _srs_dvr_async = NULL;

extern srs_error_t _srs_reload_err;
extern SrsReloadState _srs_reload_state;
extern std::string _srs_reload_id;

srs_error_t srs_global_initialize()
{
srs_error_t err = srs_success;
@@ -446,6 +450,10 @@ srs_error_t srs_global_initialize()
_srs_apm = new SrsApmClient();
#endif

_srs_reload_err = srs_success;
_srs_reload_state = SrsReloadStateInit;
_srs_reload_id = srs_random_str(7);

return err;
}