Hello,
I agree with Stipe and I think that we also have to take into
consideration the window size except the wait time when adjusting to
SMSC allowed rate. For example if SMSC allows a rate of 5 MTs/sec
there's no point to keep a window size of 10, as it should be less than
5 in this case.
Nevertheless I prepared a quick fix in current implementation to
configure a hardcoded wait time of 500 msec instead of 15 seconds. In my
case this doubled performance and actually came close to the SMSC
configured rate.
BR
>Martin Conte Mac Donell schrieb:
>> On Wed, Feb 4, 2009 at 6:51 PM, Michael Zervakis
<[email protected]> wrote:
>>> I believe that this parameter should be set optimally at msec and
not sec to
>>> handle throttling rates such as 100 messages per sec., because for each
>>> second we sleep after receiving 0x58 we lose the opportunity to
transfer
>>> these 100 messages, and transmission rate is reduced significantly.
>>
>> Maybe the "optimal" solution here is (starting for
>> SMPP_THROTTLING_MIN_TIME) increase that delay with some sort of
>> exponential growth until you reach the max defined value.
>
>I agree with Martin here.
>
>My "ideal" solution would be an dynamic exponential growth of the
sleep time,
>until we "can" send again, then calibrate to the upper bound
(throughput X/sec)
>by reducing the sleep time again.
>
>What we actually want is the "ideal" X/sec. value. We should have 2
ways do get
>this in the runtime state:
>
>a) the user sets it, if he "knows" it. But this may still lead to
throttling events.
>
>b) the smsc modules itself can handle it dynamically. We can use the user
>supplied value of a) as a "base" for the upper bound.
>
>Now, this is the network flow theory part, now who is going for the
>implementation part? ;)
>
>Stipe
? .cvsignore
Index: gw/smsc/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.112
diff -u -r1.112 smsc_smpp.c
--- gw/smsc/smsc_smpp.c 29 Jan 2009 11:38:28 -0000 1.112
+++ gw/smsc/smsc_smpp.c 9 Feb 2009 02:38:14 -0000
@@ -111,7 +111,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 500000
#define SMPP_DEFAULT_CONNECTION_TIMEOUT 10 * SMPP_ENQUIRE_LINK_INTERVAL
#define SMPP_DEFAULT_WAITACK 60
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT 30
@@ -158,7 +158,7 @@
int version;
int priority; /* set default priority for messages */
int validityperiod;
- time_t throttling_err_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;
@@ -251,7 +251,8 @@
smpp->priority = priority;
smpp->validityperiod = validity;
smpp->conn = conn;
- smpp->throttling_err_time = 0;
+ 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);
@@ -1502,10 +1503,13 @@
* 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("%ld/%s",
pdu->u.submit_sm_resp.command_status,
@@ -1641,10 +1645,13 @@
* 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,
@@ -1771,6 +1778,7 @@
SMPP_PDU *pdu;
double timeout;
time_t last_response, last_cleanup;
+ struct timeval eval_time;
io_arg = arg;
smpp = io_arg->smpp;
@@ -1792,7 +1800,8 @@
last_enquire_sent = last_cleanup = last_response =
date_universal_now();
pending_submits = -1;
len = 0;
- smpp->throttling_err_time = 0;
+ smpp->throttling_err_time.tv_sec = 0;
+ smpp->throttling_err_time.tv_usec = 0;
for (;conn != NULL;) {
timeout = last_enquire_sent + smpp->enquire_link_interval
- date_universal_now();
@@ -1845,9 +1854,11 @@
send_enquire_link(smpp, conn, &last_enquire_sent);
/* Make sure we send even if we read a lot */
- if (transmitter && difftime(time(NULL),
smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
- smpp->throttling_err_time = 0;
- send_messages(smpp, conn, &pending_submits);
+ gettimeofday(&eval_time, NULL);
+ if (transmitter && (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;
+ send_messages(smpp, conn, &pending_submits);
}
}
@@ -1873,10 +1884,13 @@
last_cleanup = time(NULL);
}
- if (transmitter && difftime(time(NULL), smpp->throttling_err_time)
> SMPP_THROTTLING_SLEEP_TIME) {
- smpp->throttling_err_time = 0;
+ gettimeofday(&eval_time, NULL);
+ if (transmitter && (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;
send_messages(smpp, conn, &pending_submits);
}
+
}
if (conn != NULL) {