Wow! Quite a patch for such a small change. I am always for patches that give more choice to the users. +1

BR,
Nikos
----- Original Message ----- From: "Michael Zervakis" <mich...@zervakis.com>
To: <devel@kannel.org>
Sent: Sunday, March 14, 2010 8:47 PM
Subject: Patch to configure sleep time when encountering SMPP throttling error


Dear all,

SMPP module has hardcoded 1 second sleep time when receiving a
throttling error from SMSC. This setting is adequate for low latency
networks but considerably limits performance when SMPP connection is
using a high latency network for example 100ms. In this case the sleep
time should be set at msec and not 1 sec. The attached patch maintains
the default 1 sec. sleep time and is introducing a new configuration
directive "throttling-sleep-time" which allows the user to define sleep
time in msec.

BR,

Michael Zervakis



--------------------------------------------------------------------------------


Index: gw/smsc/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.123
diff -u -r1.123 smsc_smpp.c
--- gw/smsc/smsc_smpp.c 2 Sep 2009 13:10:50 -0000 1.123
+++ gw/smsc/smsc_smpp.c 14 Mar 2010 18:13:21 -0000
@@ -80,6 +80,8 @@
#include "bearerbox.h"
#include "meta_data.h"
#include "load.h"
+#include <sys/time.h>
+#include <limits.h>

#define SMPP_DEFAULT_CHARSET "UTF-8"

@@ -112,7 +114,7 @@
#define SMPP_MAX_PENDING_SUBMITS    10
#define SMPP_DEFAULT_VERSION        0x34
#define SMPP_DEFAULT_PRIORITY       0
-#define SMPP_THROTTLING_SLEEP_TIME  1
+#define SMPP_THROTTLING_SLEEP_TIME  1000
#define SMPP_DEFAULT_CONNECTION_TIMEOUT  10 * SMPP_ENQUIRE_LINK_INTERVAL
#define SMPP_DEFAULT_WAITACK        60
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT 30
@@ -160,7 +162,8 @@
    int version;
    int priority;       /* set default priority for messages */
    int validityperiod;
-    time_t throttling_err_time;
+    long throttling_sleep_time;
+    struct timeval throttling_err_time;
    int smpp_msg_id_type;  /* msg id in C string, hex or decimal */
    int autodetect_addr;
    Octstr *alt_charset;
@@ -221,7 +224,7 @@
                         Octstr *my_number, int smpp_msg_id_type,
int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset,
                         Octstr *service_type, long connection_timeout,
-                         long wait_ack, int wait_ack_action)
+ long wait_ack, int wait_ack_action, int throttling_sleep_time)
{
    SMPP *smpp;

@@ -254,7 +257,9 @@
    smpp->priority = priority;
    smpp->validityperiod = validity;
    smpp->conn = conn;
-    smpp->throttling_err_time = 0;
+    smpp->throttling_sleep_time = throttling_sleep_time * 1000;
+    smpp->throttling_err_time.tv_sec = 0;
+    smpp->throttling_err_time.tv_usec = 0;
    smpp->smpp_msg_id_type = smpp_msg_id_type;
    smpp->autodetect_addr = autodetect_addr;
    smpp->alt_charset = octstr_duplicate(alt_charset);
@@ -1606,10 +1611,12 @@
* check to see if we got a "throttling error", in which case we'll just
                 * sleep for a while
                 */
- if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
-                    time(&(smpp->throttling_err_time));
-                else
-                    smpp->throttling_err_time = 0;
+ if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED) {
+                    gettimeofday(&(smpp->throttling_err_time), NULL);
+                } else {
+                    smpp->throttling_err_time.tv_sec = 0;
+                    smpp->throttling_err_time.tv_usec = 0;
+                }

bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,

smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
@@ -1755,10 +1762,12 @@
* check to see if we got a "throttling error", in which case we'll just
                 * sleep for a while
                 */
-                if (cmd_stat == SMPP_ESME_RTHROTTLED)
-                    time(&(smpp->throttling_err_time));
-                else
-                    smpp->throttling_err_time = 0;
+                if (cmd_stat == SMPP_ESME_RTHROTTLED) {
+                    gettimeofday(&(smpp->throttling_err_time), NULL);
+                } else {
+                    smpp->throttling_err_time.tv_sec = 0;
+                    smpp->throttling_err_time.tv_usec = 0;
+                }

                reason = smpp_status_to_smscconn_failure_reason(cmd_stat);
                bb_smscconn_send_failed(smpp->conn, msg, reason,
@@ -1884,6 +1893,7 @@
    SMPP_PDU *pdu;
    double timeout;
    time_t last_cleanup, last_enquire_sent, last_response, now;
+    struct timeval eval_time;

    io_arg = arg;
    smpp = io_arg->smpp;
@@ -1971,8 +1981,8 @@
                if (!IS_ACTIVE && timeout <= 0)
                    timeout = smpp->enquire_link_interval;
if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 && - smpp->throttling_err_time > 0 && pending_submits < smpp->max_pending_submits) { - time_t tr_timeout = smpp->throttling_err_time + SMPP_THROTTLING_SLEEP_TIME - now; + smpp->throttling_err_time.tv_sec > 0 && pending_submits < smpp->max_pending_submits) { + time_t tr_timeout = smpp->throttling_err_time.tv_sec + (int) (smpp->throttling_sleep_time / 1000000 + 0.5) - now;
                    timeout = timeout > tr_timeout ? tr_timeout : timeout;
} else if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 && smpp->conn->throughput > 0 &&
                           smpp->max_pending_submits > pending_submits) {
@@ -1996,10 +2006,24 @@
            }

            /* make sure we send */
- if (transmitter && difftime(time(NULL), smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
-                smpp->throttling_err_time = 0;
-                if (send_messages(smpp, conn, &pending_submits) == -1)
-                    break;
+            if (transmitter) {
+                if (smpp->throttling_err_time.tv_sec == 0) {
+ if (send_messages(smpp, conn, &pending_submits) == -1)
+                        break;
+                } else {
+                    gettimeofday(&eval_time, NULL);
+ if (eval_time.tv_sec >= smpp->throttling_err_time.tv_sec && eval_time.tv_sec - smpp->throttling_err_time.tv_sec < (unsigned long)(ULONG_MAX / 1000000 - 0.5)) { + if ((eval_time.tv_sec - smpp->throttling_err_time.tv_sec) * 1000000 + eval_time.tv_usec - smpp->throttling_err_time.tv_usec > smpp->throttling_sleep_time) {
+                             smpp->throttling_err_time.tv_sec = 0;
+                             smpp->throttling_err_time.tv_usec = 0;
+ if (send_messages(smpp, conn, &pending_submits) == -1)
+                                 break;
+                        }
+                    } else {
+ if (send_messages(smpp, conn, &pending_submits) == -1)
+                            break;
+                    }
+                }
            }

            /* unbind
@@ -2190,6 +2214,7 @@
    Octstr *alt_charset;
    Octstr *alt_addr_charset;
    long connection_timeout, wait_ack, wait_ack_action;
+    long throttling_sleep_time;

    my_number = alt_addr_charset = alt_charset = NULL;
    transceiver_mode = 0;
@@ -2229,6 +2254,9 @@
    if (cfg_get_integer(&max_pending_submits, grp,
                        octstr_imm("max-pending-submits")) == -1)
        max_pending_submits = SMPP_MAX_PENDING_SUBMITS;
+    if (cfg_get_integer(&throttling_sleep_time, grp,
+                        octstr_imm("throttling-sleep-time")) == -1)
+        throttling_sleep_time = SMPP_THROTTLING_SLEEP_TIME;

    /* Check that config is OK */
    ok = 1;
@@ -2328,7 +2356,7 @@
                       dest_addr_npi, enquire_link_interval,
max_pending_submits, version, priority, validity, my_number, smpp_msg_id_type, autodetect_addr, alt_charset, alt_addr_charset, - service_type, connection_timeout, wait_ack, wait_ack_action); + service_type, connection_timeout, wait_ack, wait_ack_action, throttling_sleep_time);

cfg_get_integer(&smpp->bind_addr_ton, grp, octstr_imm("bind-addr-ton")); cfg_get_integer(&smpp->bind_addr_npi, grp, octstr_imm("bind-addr-npi"));
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.142
diff -u -r1.142 cfg.def
--- gwlib/cfg.def 6 Dec 2009 17:24:14 -0000 1.142
+++ gwlib/cfg.def 14 Mar 2010 18:13:21 -0000
@@ -366,6 +366,7 @@
    OCTSTR(source-addr-autodetect)
    OCTSTR(enquire-link-interval)
    OCTSTR(max-pending-submits)
+    OCTSTR(throttling-sleep-time)
    OCTSTR(reconnect-delay)
    OCTSTR(transceiver-mode)
    OCTSTR(interface-version)



Reply via email to