Looks like it's going to work, but I still like the round robin idea
better. With the round robin idea you avoid the possibility of polling the
same down server repeatedly. I admit that this seems like an unlikely
event, but if you have few servers, it can be significant. (with 3 servers
this will happen 1 out nine times)

Also, as an added bonus, you can dispense with calling the random number
generation. Which can also be a significant operation. I have seen people
here discuss at length if an fsync here and there is necessary and I might
be wrong but I think calling rand is more expensive than fsync'ing...

Just my thought,
JES

Austad, Jay writes:

> Here's the modified version of qmqpc that will pick a random server instead
> of the first available.  I haven't tested it yet, but it compiles, and
> printf statements in strategic places give me the output I'm looking for.
> The rand() function is seeded with the current milliseconds from the system
> clock.  The for loop for doit() will loop twice the number of the servers we
> have to make sure it looked at all of them, this was easier than keeping
> track of which servers were already checked.  Don't make too much fun of my
> code, I haven't coded anything for about 3 years.  :)
> 
> ----------
> Jay Austad
> Network Administrator
> CBS Marketwatch
> 612.817.1271
> [EMAIL PROTECTED]
> http://cbs.marketwatch.com
> http://www.bigcharts.com
> 
>  
> 
> ===============================
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <stdlib.h>
> #include <sys/time.h>
> #include <sys/timeb.h>
> #include "substdio.h"
> #include "getln.h"
> #include "readwrite.h"
> #include "exit.h"
> #include "stralloc.h"
> #include "slurpclose.h"
> #include "error.h"
> #include "sig.h"
> #include "ip.h"
> #include "timeoutconn.h"
> #include "timeoutread.h"
> #include "timeoutwrite.h"
> #include "auto_qmail.h"
> #include "control.h"
> #include "fmt.h"
> 
> #define PORT_QMQP 628
> 
> void die_success() { _exit(0); }
> void die_perm() { _exit(31); }
> void nomem() { _exit(51); }
> void die_read() { if (errno == error_nomem) nomem(); _exit(54); }
> void die_control() { _exit(55); }
> void die_socket() { _exit(56); }
> void die_home() { _exit(61); }
> void die_temp() { _exit(71); }
> void die_conn() { _exit(74); }
> void die_format() { _exit(91); }
> 
> int lasterror = 55;
> int qmqpfd;
> 
> int saferead(fd,buf,len) int fd; char *buf; int len;
> {
>   int r;
>   r = timeoutread(60,qmqpfd,buf,len);
>   if (r <= 0) die_conn();
>   return r;
> }
> int safewrite(fd,buf,len) int fd; char *buf; int len;
> {
>   int r;
>   r = timeoutwrite(60,qmqpfd,buf,len);
>   if (r <= 0) die_conn();
>   return r;
> }
> 
> char buf[1024];
> substdio to = SUBSTDIO_FDBUF(safewrite,-1,buf,sizeof buf);
> substdio from = SUBSTDIO_FDBUF(saferead,-1,buf,sizeof buf);
> substdio envelope = SUBSTDIO_FDBUF(read,1,buf,sizeof buf);
> /* WARNING: can use only one of these at a time! */
> 
> stralloc beforemessage = {0};
> stralloc message = {0};
> stralloc aftermessage = {0};
> 
> char strnum[FMT_ULONG];
> stralloc line = {0};
> 
> struct sindex
> {
>               int pos[256];
>               int len;
> };
> 
> void getmess()
> {
>   int match;
> 
>   if (slurpclose(0,&message,1024) == -1) die_read();
> 
>   strnum[fmt_ulong(strnum,(unsigned long) message.len)] = 0;
>   if (!stralloc_copys(&beforemessage,strnum)) nomem();
>   if (!stralloc_cats(&beforemessage,":")) nomem();
>   if (!stralloc_copys(&aftermessage,",")) nomem();
> 
>   if (getln(&envelope,&line,&match,'\0') == -1) die_read();
>   if (!match) die_format();
>   if (line.len < 2) die_format();
>   if (line.s[0] != 'F') die_format();
> 
>   strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
>   if (!stralloc_cats(&aftermessage,strnum)) nomem();
>   if (!stralloc_cats(&aftermessage,":")) nomem();
>   if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
>   if (!stralloc_cats(&aftermessage,",")) nomem();
> 
>   for (;;) {
>     if (getln(&envelope,&line,&match,'\0') == -1) die_read();
>     if (!match) die_format();
>     if (line.len < 2) break;
>     if (line.s[0] != 'T') die_format();
> 
>     strnum[fmt_ulong(strnum,(unsigned long) line.len - 2)] = 0;
>     if (!stralloc_cats(&aftermessage,strnum)) nomem();
>     if (!stralloc_cats(&aftermessage,":")) nomem();
>     if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem();
>     if (!stralloc_cats(&aftermessage,",")) nomem();
>   }
> }
> 
> void doit(server)
> char *server;
> {
>   struct ip_address ip;
>   char ch;
> 
>   if (!ip_scan(server,&ip)) return;
> 
>   qmqpfd = socket(AF_INET,SOCK_STREAM,0);
>   if (qmqpfd == -1) die_socket();
> 
>   if (timeoutconn(qmqpfd,&ip,PORT_QMQP,10) != 0) {
>     lasterror = 73;
>     if (errno == error_timeout) lasterror = 72;
>     close(qmqpfd);
>     return;
>   }
> 
>   strnum[fmt_ulong(strnum,(unsigned long) (beforemessage.len + message.len +
> aftermessage.len))] = 0;
>   substdio_puts(&to,strnum);
>   substdio_puts(&to,":");
>   substdio_put(&to,beforemessage.s,beforemessage.len);
>   substdio_put(&to,message.s,message.len);
>   substdio_put(&to,aftermessage.s,aftermessage.len);
>   substdio_puts(&to,",");
>   substdio_flush(&to);
> 
>   for (;;) {
>     substdio_get(&from,&ch,1);
>     if (ch == 'K') die_success();
>     if (ch == 'Z') die_temp();
>     if (ch == 'D') die_perm();
>   }
> }
> 
> stralloc servers = {0};
> 
> main()
> {
>   int i;
>   int j;
>   int randj;
>   struct timeb tp;
>   struct sindex serverindex;     //used to keep an index of where each
> server starts in servers.s
>   
>   sig_pipeignore();
> 
>   if (chdir(auto_qmail) == -1) die_home();
>   if (control_init() == -1) die_control();
>   if (control_readfile(&servers,"control/qmqpservers",0) != 1)
> die_control();
>       
>   getmess();
> 
>   serverindex.len = 1;                //we assume that there is at least one
> server in the list
>   serverindex.pos[0]=0;
>   for (j = 0; j < servers.len; j++)
>   {
>                 if (servers.s[j] == NULL) {
>                                 serverindex.pos[serverindex.len] = j+1;
>                                 serverindex.len++;
>                 }
>   }
>   serverindex.len--;       //discard the last null character
> 
>   ftime(&tp);
>   srand(tp.millitm);  //seed rand() with milliseconds
> 
>   for (j=0; j < (serverindex.len*2); j++)
>   {
>         randj = (serverindex.len*1.0)*rand()/(RAND_MAX+1.0);
>         doit(servers.s + serverindex.pos[randj]);
>   }
>                                                 
> 
>   _exit(lasterror);
> }
> 



Reply via email to