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

Reply via email to