Re: [PATCH] SMPP Throttling

Alexander Malysh <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi,

try attached patch... main loop in smpp module should be fixed as well  
but this another story...

Thanks,
Alex




Am 10.02.2009 um 14:40 schrieb Alexander Malysh:

> Hi,
>
> yes, your patch seems to fix gwthread_wakeup but it's wrong too  
> because we _may_ not sleep on transceiver bind because we could take  
> too long to respond to dlr/mo. I have patch here for throttling,  
> will try to rebase it...
>
> Thanks,
> Alex
>
> Donald Jackson schrieb:
>> Hi everyone,
>> Here is a patch I have created for SMPP throttling. To easily
>> duplicate the bug you can take the following actions:
>> -- Configure SMPP bind with very low throughput (ie: 0.1)
>> -- Send 100 messages in quick succession
>> What you can see from the debug output times is that when
>> send_messages() is supposed to be sleeping for throttling purposes,  
>> it
>> will get woken up by send_msg_cb()'s
>> gwthread_wakeup(smpp->transmitter); call.
>> This causes inaccuracy in the sleep time as the thread is prematurely
>> woken up. This causes many throttling errors on high volume/load
>> Kannel installations because of the increased throttling errors and
>> the current default throttling sleep time which I see is being  
>> changed
>> ;) My patch simply let's send_messages() indicate that it is sleeping
>> for throttling purposes and shouldn't be woken up.
>> Good luck!
>> --
>> Donald Jackson
>> http://www.ddj.co.za/
>> donaldjster(a)gmail.com
>
>
smpp_throttling.patch (application/octet-stream, 2.9 KB)
diff --git a/gw/smsc/smsc_smpp.c b/gw/smsc/smsc_smpp.c
index 7024b63..c8e4fd3 100644
--- a/gw/smsc/smsc_smpp.c
+++ b/gw/smsc/smsc_smpp.c
@@ -79,6 +79,7 @@
 #include "dlr.h"
 #include "bearerbox.h"
 #include "meta_data.h"
+#include "load.h"
 
 #define SMPP_DEFAULT_CHARSET "UTF-8"
 
@@ -111,7 +112,7 @@
 #define SMPP_MAX_PENDING_SUBMITS    10
 #define SMPP_DEFAULT_VERSION        0x34
 #define SMPP_DEFAULT_PRIORITY       0
-#define SMPP_THROTTLING_SLEEP_TIME  15
+#define SMPP_THROTTLING_SLEEP_TIME  1
 #define SMPP_DEFAULT_CONNECTION_TIMEOUT  10 * SMPP_ENQUIRE_LINK_INTERVAL
 #define SMPP_DEFAULT_WAITACK        60
 #define SMPP_DEFAULT_SHUTDOWN_TIMEOUT 30
@@ -166,6 +167,7 @@ typedef struct {
     long connection_timeout;
     long wait_ack;
     int wait_ack_action;
+    Load *load;
     SMSCConn *conn; 
 } SMPP; 
  
@@ -261,6 +263,8 @@ static SMPP *smpp_create(SMSCConn *conn, Octstr *host, int transmit_port,
     smpp->wait_ack_action = wait_ack_action;
     smpp->bind_addr_ton = 0;
     smpp->bind_addr_npi = 0;
+    smpp->load = load_create_real(0);
+    load_add_interval(smpp->load, 1);
  
     return smpp; 
 } 
@@ -282,6 +286,7 @@ static void smpp_destroy(SMPP *smpp)
         octstr_destroy(smpp->my_number);
         octstr_destroy(smpp->alt_charset);
         octstr_destroy(smpp->alt_addr_charset);
+        load_destroy(smpp->load);
         gw_free(smpp); 
     } 
 } 
@@ -998,16 +1003,20 @@ static void send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
     Msg *msg;
     SMPP_PDU *pdu;
     Octstr *os;
-    double delay = 0;
 
     if (*pending_submits == -1)
         return;
 
-    if (smpp->conn->throughput > 0) {
-        delay = 1.0 / smpp->conn->throughput;
-    }
-
     while (*pending_submits < smpp->max_pending_submits) {
+        /* check our throughput */
+        if (smpp->conn->throughput > 0 && load_get(smpp->load, 0) >= smpp->conn->throughput) {
+            debug("bb.sms.smpp", 0, "SMPP[%s]: throughput limit exceeded (%.02f,%d)",
+                  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
+            break;
+        }
+        debug("bb.sms.smpp", 0, "SMPP[%s]: throughput (%.02f,%d)",
+              octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
+
     	/* Get next message, quit if none to be sent */
     	msg = gw_prioqueue_remove(smpp->msgs_to_send);
         if (msg == NULL)
@@ -1027,11 +1036,7 @@ static void send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
             smpp_pdu_destroy(pdu);
             octstr_destroy(os);
             ++(*pending_submits);
-            /*
-             * obey throughput speed limit, if any.
-             */
-            if (smpp->conn->throughput > 0)
-                gwthread_sleep(delay);
+            load_increase(smpp->load);
         }
         else { /* write error occurs */
             smpp_pdu_destroy(pdu);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.