mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #374, use fast stop for ingesters to stop many FFMPEG.
This commit is contained in:
parent
d611bb6b45
commit
860d68e6e7
6 changed files with 76 additions and 7 deletions
|
@ -109,12 +109,12 @@ stop() {
|
||||||
ok_msg "Stopping SRS(pid ${srs_pid})..."
|
ok_msg "Stopping SRS(pid ${srs_pid})..."
|
||||||
|
|
||||||
# process exists, try to kill to stop normally
|
# process exists, try to kill to stop normally
|
||||||
for((i=0;i<30;i++)); do
|
for((i=0;i<100;i++)); do
|
||||||
load_process_info
|
load_process_info
|
||||||
if [[ 0 -eq $? ]]; then
|
if [[ 0 -eq $? ]]; then
|
||||||
kill -s SIGTERM ${srs_pid} 2>/dev/null
|
kill -s SIGTERM ${srs_pid} 2>/dev/null
|
||||||
ret=$?; if [[ 0 -ne $ret ]]; then failed_msg "send signal SIGTERM failed ret=$ret"; return $ret; fi
|
ret=$?; if [[ 0 -ne $ret ]]; then failed_msg "send signal SIGTERM failed ret=$ret"; return $ret; fi
|
||||||
sleep 0.1
|
sleep 0.3
|
||||||
else
|
else
|
||||||
ok_msg "SRS stopped by SIGTERM"
|
ok_msg "SRS stopped by SIGTERM"
|
||||||
# delete the pid file when stop success.
|
# delete the pid file when stop success.
|
||||||
|
|
|
@ -52,6 +52,7 @@ using namespace std;
|
||||||
SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
|
SrsFFMPEG::SrsFFMPEG(std::string ffmpeg_bin)
|
||||||
{
|
{
|
||||||
started = false;
|
started = false;
|
||||||
|
fast_stopped = false;
|
||||||
pid = -1;
|
pid = -1;
|
||||||
ffmpeg = ffmpeg_bin;
|
ffmpeg = ffmpeg_bin;
|
||||||
|
|
||||||
|
@ -484,6 +485,11 @@ int SrsFFMPEG::cycle()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ffmpeg is prepare to stop, donot cycle.
|
||||||
|
if (fast_stopped) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
pid_t p = waitpid(pid, &status, WNOHANG);
|
pid_t p = waitpid(pid, &status, WNOHANG);
|
||||||
|
|
||||||
|
@ -524,6 +530,27 @@ void SrsFFMPEG::stop()
|
||||||
started = false;
|
started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsFFMPEG::fast_stop()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (!started) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kill(pid, SIGTERM) < 0) {
|
||||||
|
ret = ERROR_SYSTEM_KILL;
|
||||||
|
srs_warn("ignore fast stop ffmpeg failed, pid=%d. ret=%d", pid, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ class SrsFFMPEG
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool started;
|
bool started;
|
||||||
|
// whether SIGINT send but need to wait or SIGKILL.
|
||||||
|
bool fast_stopped;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
private:
|
private:
|
||||||
std::string log_file;
|
std::string log_file;
|
||||||
|
@ -83,7 +85,25 @@ public:
|
||||||
virtual int initialize_copy();
|
virtual int initialize_copy();
|
||||||
virtual int start();
|
virtual int start();
|
||||||
virtual int cycle();
|
virtual int cycle();
|
||||||
|
/**
|
||||||
|
* send SIGTERM then SIGKILL to ensure the process stopped.
|
||||||
|
* the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the
|
||||||
|
* process quit timeout.
|
||||||
|
* @remark use fast_stop before stop one by one, when got lots of process to quit.
|
||||||
|
*/
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* the fast stop is to send a SIGTERM.
|
||||||
|
* for example, the ingesters owner lots of FFMPEG, it will take a long time
|
||||||
|
* to stop one by one, instead the ingesters can fast_stop all FFMPEG, then
|
||||||
|
* wait one by one to stop, it's more faster.
|
||||||
|
* @remark user must use stop() to ensure the ffmpeg to stopped.
|
||||||
|
* @remark we got N processes to stop, compare the time we spend,
|
||||||
|
* when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N]
|
||||||
|
* but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
|
||||||
|
*/
|
||||||
|
virtual void fast_stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,11 @@ SrsIngesterFFMPEG::~SrsIngesterFFMPEG()
|
||||||
srs_freep(ffmpeg);
|
srs_freep(ffmpeg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsIngesterFFMPEG::fast_stop()
|
||||||
|
{
|
||||||
|
ffmpeg->fast_stop();
|
||||||
|
}
|
||||||
|
|
||||||
SrsIngester::SrsIngester()
|
SrsIngester::SrsIngester()
|
||||||
{
|
{
|
||||||
_srs_config->subscribe(this);
|
_srs_config->subscribe(this);
|
||||||
|
@ -161,6 +166,18 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
|
||||||
|
|
||||||
void SrsIngester::dispose()
|
void SrsIngester::dispose()
|
||||||
{
|
{
|
||||||
|
// first, use fast stop to notice all FFMPEG to quit gracefully.
|
||||||
|
std::vector<SrsIngesterFFMPEG*>::iterator it;
|
||||||
|
for (it = ingesters.begin(); it != ingesters.end(); ++it) {
|
||||||
|
SrsIngesterFFMPEG* ingester = *it;
|
||||||
|
ingester->fast_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ingesters.empty()) {
|
||||||
|
srs_trace("fast stop all ingesters ok.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// then, use stop to wait FFMPEG quit one by one and send SIGKILL if needed.
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@ public:
|
||||||
|
|
||||||
SrsIngesterFFMPEG(SrsFFMPEG* _ffmpeg, std::string _vhost, std::string _id);
|
SrsIngesterFFMPEG(SrsFFMPEG* _ffmpeg, std::string _vhost, std::string _id);
|
||||||
virtual ~SrsIngesterFFMPEG();
|
virtual ~SrsIngesterFFMPEG();
|
||||||
|
|
||||||
|
// @see SrsFFMPEG.fast_stop().
|
||||||
|
virtual void fast_stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,6 +44,9 @@ using namespace std;
|
||||||
#include <srs_app_json.hpp>
|
#include <srs_app_json.hpp>
|
||||||
#include <srs_kernel_stream.hpp>
|
#include <srs_kernel_stream.hpp>
|
||||||
|
|
||||||
|
// the longest time to wait for a process to quit.
|
||||||
|
#define SRS_PROCESS_QUIT_TIMEOUT_MS 1000
|
||||||
|
|
||||||
int srs_socket_connect(string server, int port, int64_t timeout, st_netfd_t* pstfd)
|
int srs_socket_connect(string server, int port, int64_t timeout, st_netfd_t* pstfd)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -223,7 +226,6 @@ void srs_parse_endpoint(string ip_port, string& ip, int& port)
|
||||||
port = ::atoi(the_port.c_str());
|
port = ::atoi(the_port.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SRS_PROCESS_QUIT_TIMEOUT_MS 1000
|
|
||||||
int srs_kill_forced(int& pid)
|
int srs_kill_forced(int& pid)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -232,13 +234,13 @@ int srs_kill_forced(int& pid)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first, try kill by SIGINT.
|
// first, try kill by SIGTERM.
|
||||||
if (kill(pid, SIGINT) < 0) {
|
if (kill(pid, SIGTERM) < 0) {
|
||||||
return ERROR_SYSTEM_KILL;
|
return ERROR_SYSTEM_KILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait to quit.
|
// wait to quit.
|
||||||
srs_trace("send SIGINT to pid=%d", pid);
|
srs_trace("send SIGTERM to pid=%d", pid);
|
||||||
for (int i = 0; i < SRS_PROCESS_QUIT_TIMEOUT_MS / 10; i++) {
|
for (int i = 0; i < SRS_PROCESS_QUIT_TIMEOUT_MS / 10; i++) {
|
||||||
int status = 0;
|
int status = 0;
|
||||||
pid_t qpid = -1;
|
pid_t qpid = -1;
|
||||||
|
@ -253,7 +255,7 @@ int srs_kill_forced(int& pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// killed, set pid to -1.
|
// killed, set pid to -1.
|
||||||
srs_trace("SIGINT stop process pid=%d ok.", pid);
|
srs_trace("SIGTERM stop process pid=%d ok.", pid);
|
||||||
pid = -1;
|
pid = -1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue