cde87e3d79ee923945b80b85d708ab9d07475263
hiram
  Wed Sep 1 13:26:02 2021 -0700
improved bottleneck penalty for custom track loading even when they fail to load refs #28049

diff --git src/hg/lib/customTrack.c src/hg/lib/customTrack.c
index c844aec..291879d 100644
--- src/hg/lib/customTrack.c
+++ src/hg/lib/customTrack.c
@@ -936,44 +936,53 @@
                     if (html && differentString(html, ct->tdb->html))
                         {
                         ct->tdb->html = html;
                         changedCt = TRUE;
                         }
                     }
                 break;
                 }
             }
         }
     cartRemove(cart, CT_SELECTED_TABLE_VAR);
     }
 
 /* merge new and old tracks */
 numAdded = slCount(newCts);
-if (numAdded)
+/* add delay even if numAdded==0 because that can be when the loading
+ * of the custom tracks failed.  The try is worth the penalty.
+ */
+if (numAdded >= 0)
     {
+    static int botCheckMult = 0;
+    if (0 == botCheckMult)      // only on first time through here
+	{                       // default is 1 when not specified
+	char *val = cfgOptionDefault("customTracks.botCheckMult", "1");
+        botCheckMult = sqlSigned(val);
+        if (botCheckMult < 1)   // protect against negative value
+	    botCheckMult = 1;   // default is 1, no maximum check here
+	}
     fprintf(stderr, "customTrack: new %d from %s\n", numAdded, customText);
     printSaveList = TRUE;
     /* add penalty in relation to number of tracks created
-     * the delayFraction here is 0.25 as it is in hgTracks
-     * the enteredMainTime is 0 since this is not important here
-     * the warnMs and exitMs are set at 1,000,000 since we do *not* want
-     * any exit or warning here, and the return code issueBotWarning is ignored
-     * this is merely to accumulate penalty time.  The name "hgTracks" here
-     * is unimportant, it is not going to be used.  Other CGIs besides hgTracks
-     * will be calling here.
+     * the default delayFraction here is 1, can be hg.conf specified
+     * this call to hgBotDelayTimeFrac will merely add this penalty
+     * to the existing delay time, there will be no sleeping here, that will
+     * happen upon the next execution for the next CGI from that IP address.
+     * Other CGIs besides hgTracks can be calling here.
      */
-    (void) earlyBotCheck(0, "hgTracks", (double)(numAdded + 1) * 0.25, 1000000, 1000000, "html");
+    botDelayMillis = hgBotDelayTimeFrac((double)((numAdded + 1)*botCheckMult));
     }
 
 ctList = customTrackAddToList(ctList, newCts, &replacedCts, FALSE);
 for (ct = ctList; ct != NULL; ct = ct->next)
     if (trackDbSetting(ct->tdb, CT_UNPARSED))
         {
         ctRemoveFromSettings(ct, CT_UNPARSED);
         changedCt = TRUE;
         }
 if (newCts || removedCt || changedCt || ctConfigUpdate(ctFileName))
     {
     customTracksSaveCart(genomeDb, cart, ctList);
     // If all CTs have been removed then customTrackFileVar is also removed from cart, so optional:
     ctFileName = cartOptionalString(cart, customTrackFileVar(genomeDb));
     }