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);