> I agree with Tom though...let exim's internal queue functions handle > it since it's already doing whatever you'd be scripting and it works > in parallel.
Actually, I do run a scripted queue runner replacement for performance reasons on my outgoing machines. I wrote this once before, but anyway: Exim does not coordinate its queue runners. If you have too few, you waste throughput. If you have enough, they step on each others toes by trying to deliver messages currently being delivered by another queue runner or by trying a message just having been tried by another queue runner, just to find out it was just tried, while letting other messages starve. It is way cheaper to deliver mails instantly than to queue them first, but if you can not but have a queue in between 15 and 150 thousand messages, a coordinated approach might solve the problem. It certainly does it for me. Be aware that you end up with more than 300 parallel deliveries, though, if messages have more than one recipient. That's one reason why Exim works differently, but my machines didn't come with a tag "do not exceed 300 parallel deliveries", so I don't care. :-) ---------------------------------------------------------------------- #!/bin/rc CONCURRENCY=300 echo 'Exim queue runner started.' exec >/dev/null >[2=1] </dev/null fn sighup {} @{ @{ while (true) { /usr/exim/bin/exim -bpra; sleep 120 } } | awk '{ id=$3 do { getline } while ($0!="") print "exec /usr/exim/bin/exim -Mc " id }' | parsh $CONCURRENCY } & ---------------------------------------------------------------------- #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { char ln[4096],*end; int p,res=0,status=0,usage=0; if (argc!=2) usage=1; else { p=strtol(argv[1],&end,10); if (*end || p<1) usage=1; } if (usage) { fprintf(stderr,"Usage: parsh parallelity\n"); exit(1); } while (fgets(ln,sizeof(ln),stdin)) { if (p==0) { wait(&status); ++p; } if (res==0 && status) res=status; switch (vfork()) { case 0: { execl("/bin/sh","sh","-c",ln,(const char*)0); fprintf(stderr,"parsh: exec failed: %s\n",strerror(errno)); exit(2); break; } case -1: { fprintf(stderr,"parsh: vfork failed: %s\n",strerror(errno)); exit(2); break; } default: --p; } } while (wait(&status)!=-1) if (res==0 && status) res=status; return res; } ---------------------------------------------------------------------- Michael -- ## List details at http://www.exim.org/mailman/listinfo/exim-users ## Exim details at http://www.exim.org/ ## Please use the Wiki with this list - http://www.exim.org/eximwiki/