---------- Forwarded message ----------
Date: Mon, 04 Oct 2004 17:06:44 +0200
From: Stephane DAVY <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: [squid-users] Patch for load-balancing et HA in Squid-ICAP client

Hello,

please find below a message posted on the squid-icapClient ML. Actually,
there is not so much activity on this list even if people are interested
in ICAP stuff in Squid. This message deals with HA and load-balancing,
and testing is needed so any feedback is welcome.

Thanks,

Stéphane



Objet: [squid-icapClient] Patch for load-balancing et HA
Date: Mon, 04 Oct 2004 14:54:34 +0200
Hello all,

here is a patch from Luc Saillard (Alcove company) which implements
load-balancing and HA. You can define a service using different
serveurs, and for each request we take the next server if this one is
reachable:
icap_service service_1 reqmod_precache icap://server1:1344/wwreqmod
icap_service service_1 reqmod_precache icap://server2:1344/wwreqmod
icap_service service_1 reqmod_precache icap://server3:1344/wwreqmod


The patch should be applied against the latest tarball available here: http://www.squid-cache.org/~wessels/squid-icap-2.5/

Dont' forget to run bootstrap.sh before configure

Feedback is welcome at the following address:
[EMAIL PROTECTED] and of course on this ML

Enjoy!

--
Stephane DAVY <[EMAIL PROTECTED]>
--- squid-icap-2.5-200409161544.orig/src/cache_cf.c	Wed Aug  4 21:47:58 2004
+++ squid-icap-2.5-200409161544/src/cache_cf.c	Tue Sep 28 15:44:03 2004
@@ -2299,13 +2299,27 @@
  */
 
 static void
-icap_service_list_add(icap_service_list ** isl, icap_service * service)
+icap_service_list_add(icap_service_list ** isl, char * service_name)
 {
     icap_service_list **iter;
     icap_service_list *new;
+    icap_service      *gbl_service;
+    int	              i;
+    int		      max_services;
 
     new = memAllocate(MEM_ICAP_SERVICE_LIST);
-    new->service = service;
+    /* Found all services with that name, and add to the array */
+    max_services = sizeof(new->services)/sizeof(icap_service *);
+    gbl_service = Config.icapcfg.service_head;
+    i=0;
+    while(gbl_service && i < max_services) {
+       if (!strcmp(service_name, gbl_service->name)) {
+	  new->services[i++] = gbl_service;
+	  break;
+       }
+       gbl_service = gbl_service->next;
+    }
+    new->nservices = i;
 
     if (*isl) {
 	iter = isl;
@@ -2400,7 +2414,7 @@
     for (iter = c->services; iter; iter = iter->next) {
 	service = icap_service_lookup(iter->key);
 	if (service) {
-	    icap_service_list_add(&isl, service);
+	    icap_service_list_add(&isl, iter->key);
 	} else {
 	    debug(3, 0) ("icap_class_process (line %d): skipping service %s in class %s\n", config_lineno, iter->key, c->name);
 	}
@@ -2493,7 +2507,9 @@
 		c->hidden = 1;
 		wordlistAdd(&c->services, A->service_name);
 		c->isl = memAllocate(MEM_ICAP_SERVICE_LIST);
-		c->isl->service = s;
+		/* FIXME:luc: check what access do */
+		c->isl->services[0] = s;
+		c->isl->nservices = 1;
 		icap_class_add(c);
 		A->class = c;
 	    } else {
@@ -2592,7 +2608,9 @@
 	printf("  %s: \n", c_iter->name);
 	printf("    services = \n");
 	for (isl_iter = c_iter->isl; isl_iter; isl_iter = isl_iter->next) {
-	    printf("      %s\n", isl_iter->service->name);
+	   int i;
+	   for (i = 0; i < isl_iter->nservices; i++)
+	     printf("      %s\n", isl_iter->services[i]->name);
 	}
     }
     debug(3, 0) ("IcapConfig: access =\n");
--- squid-icap-2.5-200409161544.orig/src/icap_common.c	Sat Apr  3 23:12:55 2004
+++ squid-icap-2.5-200409161544/src/icap_common.c	Tue Sep 28 15:36:03 2004
@@ -140,6 +140,8 @@
 icapService(icap_service_t type, request_t * r)
 {
     icap_service_list *isl_iter;
+    int is_iter;
+
     debug(81, 8) ("icapService: type=%s\n", icapServiceToStr(type));
     if (NULL == r) {
 	debug(81, 8) ("icapService: no request_t\n");
@@ -150,10 +152,27 @@
 	return NULL;
     }
     for (isl_iter = r->class->isl; isl_iter; isl_iter = isl_iter->next) {
-	if (type == isl_iter->service->type) {
-	    debug(81, 8) ("icapService: found service %s\n", isl_iter->service->name);
-	    return isl_iter->service;
-	}
+        /* TODO:luc: Do a round-robin, choose a random value ? 
+	 * For now, we use a simple round robin with checking is the
+	 * icap server is available */
+	is_iter = isl_iter->last_service_used;
+	do
+	 {
+	   is_iter = (is_iter + 1) % isl_iter->nservices;
+	   debug(81, 9) ("icapService: checking service %s/id=%d\n",isl_iter->services[is_iter]->name,is_iter);
+	   if (type == isl_iter->services[is_iter]->type)
+	    {
+	      if (!isl_iter->services[is_iter]->unreachable)
+	       {
+		 debug(81, 8) ("icapService: found service %s/id=%d\n", isl_iter->services[is_iter]->name,is_iter);
+		 isl_iter->last_service_used = is_iter;
+		 return isl_iter->services[is_iter];
+	       }
+	      debug(81, 8) ("icapService: found service %s/id=%d, but it's unreachable. I don't want to use it\n", isl_iter->services[is_iter]->name,is_iter);
+	      /* FIXME:luc: in response mod, if we return an NULL pointer, user can bypass
+	       * the filter, is it normal ? */
+	    }
+	 } while (is_iter != isl_iter->last_service_used);
     }
     debug(81, 8) ("icapService: no service found\n");
     return NULL;
--- squid-icap-2.5-200409161544.orig/src/structs.h	Wed Aug  4 21:48:08 2004
+++ squid-icap-2.5-200409161544/src/structs.h	Tue Sep 28 13:05:08 2004
@@ -1085,7 +1085,9 @@
 
 struct _icap_service_list {
     icap_service_list *next;
-    icap_service *service;
+    icap_service *services[16];
+    int nservices;		/* Number of services already used */
+    int last_service_used;	/* Last services used, use to do a round robin */
 };
 
 struct _icap_class {

Reply via email to