[PATCH] dlr retries

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

This patch implements an "sleep and retry" when calling dlr_get().  
This aims to solve the problem we were having with dlr's arriving  
before the row is inserted.

2 new core parameters are defined:

dlr-retry-count -> How many times do we attempt to fetch the dlr?  
Default: 1
dlr-retry-delay -> How many milliseconds do we sleep before retrying?  
Default: 0

So, if you don't set these parameters the behaviour remains as it was  
before patching. However, if you, for example, set:

dlr-retry-count = 3
dlr-retry-delay = 200

Kannel will try 3 times in total (the original one plus 2 more),  
pausing 200ms (0.2 seconds) before each attempt. If after the third  
attempt the DLR's still missing, Kannel will display a warning as usual.




Regards,
--
Alejandro Guerrieri
[email protected]
kannel-dlr-retry.patch (application/octet-stream, 3.4 KB)
Index: gwlib/cfg.def
===================================================================
--- gwlib/cfg.def	(revision 28)
+++ gwlib/cfg.def	(working copy)
@@ -119,6 +119,8 @@
     OCTSTR(ssl-server-key-file)
     OCTSTR(ssl-trusted-ca-file)
     OCTSTR(dlr-storage)
+    OCTSTR(dlr-retry-count)
+    OCTSTR(dlr-retry-delay)
     OCTSTR(maximum-queue-length)
     OCTSTR(sms-incoming-queue-limit)
     OCTSTR(sms-outgoing-queue-limit)
Index: gw/dlr.c
===================================================================
--- gw/dlr.c	(revision 27)
+++ gw/dlr.c	(working copy)
@@ -228,6 +228,7 @@
 {
     CfgGroup *grp;
     Octstr *dlr_type;
+    long retry_delay;
 
     /* check which DLR storage type we are using */
     grp = cfg_get_single_group(cfg, octstr_imm("core"));
@@ -269,6 +270,14 @@
     /* check needed function pointers */
     if (handles->dlr_add == NULL || handles->dlr_get == NULL || handles->dlr_remove == NULL)
         panic(0, "DLR: storage type '%s' don't implement needed functions", octstr_get_cstr(dlr_type));
+    
+    if (cfg_get_integer(&handles->retry_count, grp, octstr_imm("dlr-retry-count")) == -1) {
+    	handles->retry_count = 1;
+    }
+    if (cfg_get_integer(&retry_delay, grp, octstr_imm("dlr-retry-delay")) == -1) {
+    	retry_delay = 0;
+    }
+    handles->retry_delay = (double)retry_delay/1000.0;
 
     /* get info from storage */
     info(0, "DLR using storage type: %s", handles->type);
@@ -364,6 +373,7 @@
 {
     Msg	*msg = NULL;
     struct dlr_entry *dlr = NULL;
+    int retry = 0;
     
     if(octstr_len(smsc) == 0) {
 	warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type());
@@ -377,13 +387,30 @@
     debug("dlr.dlr", 0, "DLR[%s]: Looking for DLR smsc=%s, ts=%s, dst=%s, type=%d",
                                  dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(ts), octstr_get_cstr(dst), typ);
 
-    dlr = handles->dlr_get(smsc, ts, dst);
-    if (dlr == NULL)  {
-        warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found.",
-                dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst));         
-        return NULL;
+	/*
+	 * Retry the dlr search on the DB if not found at first attempt.
+	 * This could happen specially with DB storage when using separate
+	 * binds for sending and receiving.
+	 */
+    while(retry < handles->retry_count) {
+    	if (retry++ > 0) {
+    		debug("dlr.dlr", 0, "Sleeping for %1.3f seconds", handles->retry_delay);
+    		gwthread_sleep(handles->retry_delay);
+    	}
+    	dlr = handles->dlr_get(smsc, ts, dst);
+
+    	if (dlr != NULL)
+			break;
+
+		debug("dlr.dlr", 0, "DLR from SMSC<%s> for DST<%s>. Attempt %d of %d.",
+				octstr_get_cstr(smsc), octstr_get_cstr(dst), retry, handles->retry_count);
     }
 
+    if (dlr == NULL) {
+		warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found after %d attempts.",
+				dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst), handles->retry_count);
+		return NULL;
+    }
 #define O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; }
 
     if ((typ & dlr->mask) > 0) {
Index: gw/dlr_p.h
===================================================================
--- gw/dlr_p.h	(revision 27)
+++ gw/dlr_p.h	(working copy)
@@ -137,6 +137,14 @@
      * Shutdown storage
      */
     void (*dlr_shutdown) (void);
+    /*
+     * How many times do we retry the dlr_find?
+     */
+    long retry_count;
+    /*
+     * Delay between the retries 
+     */
+    double retry_delay;
 };
 
 /*
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.