Re: Patch to configure sleep time when encountering SMPP throttling error
"Nikos Balkanas" <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <3A677880BC41450E8FF343950D04AE3F@drwho> |
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" <[email protected]> To: <[email protected]> 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) >