The 3 attached patches to 3 files adds two new config options to LPRng.
This is the first version and hopefully the last. My milage do vary. The
patches are coded in the same style as existing code to keep with the
LPRNG coding standard.
chooser_once_per_queue
----------------------
If you enable "chooser_once_per_queue" in your lpd.conf/printcap then the
code in lpd_conf.c will only call your chooser program/routine once per
queue (for the first available job) and NOT for _each_ available job in
the queue. Then it will wait chooser_interval before trying once again
(instead of calling it for _each_ job in the queue and then waiting
chooser_interval).
This is very handy when you want to load balance over queues and are not
interested in load balancing on job owner/content level. I think most
people just want to pick the most available (best) printer (queue).
Without this option a server can go on its knees if the load balance queue
has lots of jobs as LPRng will do nothing but spawning the chooser program
for each job. (Add a few load balance queues full of jobs and do the math
yourself.) So if you just want your chooser program to pick a queue (as
you don't want to only round-robin) this feature is for you. [For example,
my chooser program verifies the printer is up and running before accepting
jobs for its queue as round-robin will place jobs in the queue even if the
printer is down. My program also picks an idle printer over one that is
printing, and a printer with lots of toner/paper than one with low toner
or low paper. I only need to call once per queue each rotation, so I need
this feature.]
chooser_only_if_available_sv
----------------------------
If you enable "chooser_only_if_available_sv" in your lpd.conf/printcap
then the chooser program/routine is not called at all if there are no
available (i.e. empty) serving queues (slaves). I thought this is quite
useful as it is a waste of resources to call an external chooser program
with no printers to choose from, so it just have to return JFAIL (no
queue) [or JSUCC with no queue on stdout]. This choice could be done
inside lpd_jobs, saving that every expensive call to the chooser program.
The patche are of course released under the GNU GPL (like LPRng) and may
be included in LPRng without further permission.
Yours sincerely,
Henrik
--- lp.h.orig Wed Apr 16 01:37:43 2003
+++ lp.h Wed Sep 3 15:24:19 2003
@@ -267,6 +267,8 @@
EXTERN int Check_for_protocol_violations_DYN; /* check for RFC1179 protocol
violations */
EXTERN char* Chooser_DYN; /* choose the destination for a load balance queue */
EXTERN int Chooser_interval_DYN; /* interval between tests for load balance
destination */
+EXTERN int Chooser_once_per_queue_DYN; /* only call the chooser once per queue
instead for each job in the queue before waiting chooser_interval */
+EXTERN int Chooser_only_if_available_sv_DYN; /* only call the chooser if there are
at least one available printers to feed to it */
EXTERN char* Chooser_routine_DYN; /* choose the destination for a load balance
queue */
EXTERN int Class_in_status_DYN; /* Show class in status information */
EXTERN char* Comment_tag_DYN; /* comment identifying printer (LPQ) */
--- vars.c.orig Wed Apr 16 01:37:42 2003
+++ vars.c Wed Sep 3 15:26:35 2003
@@ -160,6 +160,10 @@
{ "chooser", 0, STRING_K, &Chooser_DYN,0,0,0},
/* interval between checks for available destination for load balance queue */
{ "chooser_interval", 0, INTEGER_K, &Chooser_interval_DYN,0,0,"=10"},
+ /* only call the chooser once per queue instead for each job in the queue before
waiting chooser_interval */
+{ "chooser_once_per_queue", 0, FLAG_K, &Chooser_once_per_queue_DYN,0,0,0},
+ /* only call the chooser if there are at least one available printers to feed to
it */
+{ "chooser_only_if_available_sv", 0, FLAG_K, &Chooser_only_if_available_sv_DYN,0,0,0},
/* user provided routine selects the destination for a load balance queue */
{ "chooser_routine", 0, FLAG_K, &Chooser_routine_DYN,0,0,0},
/* show classname in status display */
--- lpd_jobs.c.orig Wed Apr 16 01:37:42 2003
+++ lpd_jobs.c Wed Sep 3 18:05:54 2003
@@ -852,7 +852,12 @@
* :sv == "" - then we do
*/
DEBUG1("Do_queue_jobs: Chooser %s, working %d, master
%d", Chooser_DYN, working, master);
- if( (Chooser_routine_DYN || Chooser_DYN) && working &&
master == 0 ){
+ if( Chooser_only_if_available_sv_DYN &&
(Chooser_routine_DYN || Chooser_DYN) && chooser_list.count == 0 ){
+ /* we do not want to call the chooser
+ * if there were no available printers
+ */
+ chooser_did_not_find_server = 1;
+ } else if( (Chooser_routine_DYN || Chooser_DYN) &&
working && master == 0 ){
chooser_did_not_find_server = 1;
} else if( Chooser_routine_DYN ){
#if defined(CHOOSER_ROUTINE)
@@ -959,6 +964,7 @@
if( out_tempfd >= 0 ) close( out_tempfd ); out_tempfd
= -1;
Free_line_list( &chooser_env );
Free_line_list( &chooser_list );
+ if( Chooser_once_per_queue_DYN &&
chooser_did_not_find_server == 1 ) break;
}
}