On 2011 January 13, Thursday 15:21:11 Stefan Sayer wrote:
> If you have any contributions to share, or are aware of any issues in
> 1.4-dev version, now it may be a good time to have them included in
> the 1.4 release.
Hi,
Attached is a patch that adds the "graceful shutdown" functionality to SEMS:
Using the Stats interface, one can switch on and off the shutdown mode. In
shutdown mode, SEMS will reject the incoming INVITEs with a configurable error
code/error message, also it will reply with the same message to the OPTIONS
requests. There is also a "session kill" mode, it flips a boolean flag to true
which the applications can check and act accordingly (send BYE to the peers,
play a goodbye message or do whatever needed to gracefully shut down the
sessions). These two conditions are reversible and semi-dependent on
eachother: turning on session kill implies turning on shutdown mode, turning
off shutdown mode implies turning off session kill.
I also have the 1.3.1 version of my "detailed statistics" patch I sent on 8th
of March 2010, if you need it I can send it again.
br
Szo
diff -ruwx .svn sems-orig/core//AmConfig.cpp sems-new/core//AmConfig.cpp
--- sems-orig/core//AmConfig.cpp 2011-01-31 16:26:08.000000000 +0100
+++ sems-new/core//AmConfig.cpp 2011-02-01 16:29:22.000000000 +0100
@@ -91,6 +91,12 @@
unsigned int AmConfig::OptionsSessionLimitErrCode = 503;
string AmConfig::OptionsSessionLimitErrReason = "Server overload";
+bool AmConfig::ShutdownMode = false;
+unsigned int AmConfig::ShutdownModeErrCode = 503;
+string AmConfig::ShutdownModeErrReason = "Server shutting down";
+bool AmConfig::RedFlag = false;
+
unsigned char AmConfig::rel100 = REL100_SUPPORTED;
vector <string> AmConfig::CodecOrder;
@@ -523,6 +529,18 @@
}
}
+ if(cfg.hasParameter("shutdown_mode")){
+ vector<string> limit = explode(cfg.getParameter("shutdown_mode"), ";");
+ if (limit.size() != 2) {
+ ERROR("invalid shutdown_mode specified.\n");
+ } else {
+ if (str2i(limit[0], ShutdownModeErrCode)) {
+ ERROR("invalid shutdown_mode specified.\n");
+ }
+ ShutdownModeErrReason = limit[1];
+ }
+ }
+
if (cfg.hasParameter("100rel")) {
string rel100s = cfg.getParameter("100rel");
if (rel100s == "disabled" || rel100s == "off") {
diff -ruwx .svn sems-orig/core//AmConfig.h sems-new/core//AmConfig.h
--- sems-orig/core//AmConfig.h 2011-01-31 16:26:08.000000000 +0100
+++ sems-new/core//AmConfig.h 2011-02-01 16:29:22.000000000 +0100
@@ -135,6 +135,12 @@
static unsigned int OptionsSessionLimitErrCode;
static string OptionsSessionLimitErrReason;
+ static bool ShutdownMode;
+ static unsigned int ShutdownModeErrCode;
+ static string ShutdownModeErrReason;
+ static bool RedFlag;
+
static unsigned char rel100;
/** Time of no RTP after which Session is regarded as dead, 0 for no Timeout */
diff -ruwx .svn sems-orig/core//AmSessionContainer.cpp sems-new/core//AmSessionContainer.cpp
--- sems-orig/core//AmSessionContainer.cpp 2011-01-31 16:26:08.000000000 +0100
+++ sems-new/core//AmSessionContainer.cpp 2011-02-01 16:29:22.000000000 +0100
@@ -374,6 +374,15 @@
return NULL;
}
+ if (AmConfig::ShutdownMode) {
+ _run_cond.set(true); // so that thread stops
+ DBG("Shutdown mode. Not creating session.\n");
+
+ AmSipDialog::reply_error(req,AmConfig::ShutdownModeErrCode,
+ AmConfig::ShutdownModeErrReason);
+ return NULL;
+ }
+
AmSessionFactory* session_factory =
AmPlugIn::instance()->findSessionFactory(req);
diff -ruwx .svn sems-orig/core//AmSipDispatcher.cpp sems-new/core//AmSipDispatcher.cpp
--- sems-orig/core//AmSipDispatcher.cpp 2011-01-31 16:26:08.000000000 +0100
+++ sems-new/core//AmSipDispatcher.cpp 2011-02-01 16:29:22.000000000 +0100
@@ -96,14 +96,19 @@
else if(req.method == "OPTIONS"){
// Basic OPTIONS support
- if (!AmConfig::OptionsSessionLimit ||
- (AmSession::getSessionNum() < AmConfig::OptionsSessionLimit)) {
- AmSipDialog::reply_error(req, 200, "OK");
- } else {
+ if (AmConfig::OptionsSessionLimit &&
+ (AmSession::getSessionNum() >= AmConfig::OptionsSessionLimit)) {
// return error code if near to overload
AmSipDialog::reply_error(req,
AmConfig::OptionsSessionLimitErrCode,
AmConfig::OptionsSessionLimitErrReason);
+ } else if (AmConfig::ShutdownMode) {
+ // return error code if in shutdown mode
+ AmSipDialog::reply_error(req,
+ AmConfig::ShutdownModeErrCode,
+ AmConfig::ShutdownModeErrReason);
+ } else {
+ AmSipDialog::reply_error(req, 200, "OK");
}
return;
diff -ruwx .svn sems-orig/core//plug-in/stats/StatsUDPServer.cpp sems-new/core//plug-in/stats/StatsUDPServer.cpp
--- sems-orig/core//plug-in/stats/StatsUDPServer.cpp 2011-01-31 16:26:08.000000000 +0100
+++ sems-new/core//plug-in/stats/StatsUDPServer.cpp 2011-02-01 16:29:22.000000000 +0100
@@ -241,12 +241,35 @@
if(cmd_str == "calls")
reply = "Active calls: " + int2str(AmSession::getSessionNum()) + "\n";
else if (cmd_str == "which") {
reply =
"calls - number of active calls (Session Container size)\n"
"which - print available commands\n"
"set_loglevel <loglevel> - set log level\n"
"get_loglevel - get log level\n"
+ "set_shutdownmode - turns on and off shutdown mode\n"
+ "get_shutdownmode - returns the shutdown mode's current state\n"
+ "set_sessionshutdown - turns on and off session shutdown\n"
+ "get_sessionshutdown - returns the session shutdown's current state\n"
+ "When in shutdown mode, SEMS will answer with the configured 5xx errorcode to\n"
+ "new INVITE and OPTIONS requests. The session shutdown mode will force\n"
+ "the currently active sessions to end if the handling plug-in supports it.\n"
+ "Turning off the shutdown mode will force the session shutdown off too.\n"
+ "Turning on the session shutdown mode will force the shutdown mode on too.\n"
+
"\n"
"DI <factory> <function> (<args>)* - invoke DI command\n"
;
@@ -259,7 +282,44 @@
else
reply= "loglevel set to "+int2str(log_level)+".\n";
}
+ else if (cmd_str.substr(4, 12) == "shutdownmode") {
+ int tmp;
+ if(sscanf(&cmd_str.c_str()[17],"%u",&tmp) != 1)
+ reply= "invalid shutdownmode\n";
+ else
+ {
+ if(tmp)
+ {
+ AmConfig::ShutdownMode = true;
+ reply= "Shutdownmode activated!\n";
+ }
+ else
+ {
+ AmConfig::ShutdownMode = false;
+ AmConfig::RedFlag = false;
+ reply= "Shutdownmode deactivated!\n";
+ }
+ }
+ }
+ else if (cmd_str.substr(4, 15) == "sessionshutdown") {
+ int tmp;
+ if(sscanf(&cmd_str.c_str()[20],"%u",&tmp) != 1)
+ reply= "invalid sessionshutdown\n";
+ else
+ {
+ if(tmp)
+ {
+ AmConfig::ShutdownMode = true;
+ AmConfig::RedFlag = true;
+ reply= "Session shutdown activated!\n";
+ }
+ else
+ {
+ AmConfig::RedFlag = false;
+ reply= "Session shutdown deactivated!\n";
+ }
+ }
+ }
else reply = "Unknown command: '" + cmd_str + "'\n";
}
else if (cmd_str.length() > 4 && cmd_str.substr(0, 4) == "get_") {
@@ -267,6 +327,29 @@
if (cmd_str.substr(4, 8) == "loglevel") {
reply= "loglevel is "+int2str(log_level)+".\n";
}
+ else if (cmd_str.substr(4, 12) == "shutdownmode") {
+ if(AmConfig::ShutdownMode)
+ {
+ reply= "Shutdownmode active!\n";
+ }
+ else
+ {
+ reply= "Shutdownmode inactive!\n";
+ }
+ }
+ else if (cmd_str.substr(4, 15) == "sessionshutdown") {
+ if(AmConfig::RedFlag)
+ {
+ reply= "Session shutdown active!\n";
+ }
+ else
+ {
+ reply= "Session shutdown inactive!\n";
+ }
+ }
else reply = "Unknown command: '" + cmd_str + "'\n";
}
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev