a9a5f7734677310cd261bc0ba8cfe7f1d83754b4
galt
  Mon Jun 17 13:47:04 2019 -0700
Improved the method for waiting for completion in the hgSession save custom tracks as archive. This should fix the problem session found on genome-euro. refs #23628

diff --git src/hg/hgSession/backup.c src/hg/hgSession/backup.c
index 76a80b8..f0798ff 100644
--- src/hg/hgSession/backup.c
+++ src/hg/hgSession/backup.c
@@ -66,90 +66,102 @@
 va_list args;
 va_start(args, format);
 vaHtmlOpen(format, args);
 va_end(args);
 }
 
 void htmlClose()
 /* Close down html format page. */
 {
 popWarnHandler();
 cartWebEnd();
 }
 
 // ------------------------------------------
 
-
-void getBackgroundStatus(char *url)
-/* fetch status as the latest complete html block available.
- * fetch progress info instead if background proc still running. */
+boolean waitForBackgroundFile(char *path)
+/* Wait 30 seconds for the file at path to appear. Return TRUE if timeout exceeded. */
 {
-char *html = NULL;
 int waited = 0;
+int waitLimit = 30;   // max wait in seconds
 // sometimes the background process is a little slow,
-// we can wait up to 60 seconds for it.
-while ((fileSize(url)==0) && (waited < 60))
+// we can wait up to 30 seconds for it.
+while (!(fileExists(path) && fileSize(path) > 0) && (waited < waitLimit))
     {
     sleep(1);
     ++waited;
     }
-if (fileSize(url)==0)
+if (waited >= waitLimit)
     {
     htmlOpen("Background Status");
-    errAbort("No output found. Expecting output in [%s].", url);
+    errAbort("Background file %s not found or empty.", path);
     htmlClose();
-    return;
+    return TRUE;
     }
+return FALSE;
+}
+
+void getBackgroundStatus(char *url)
+/* fetch status as the latest complete html block available.
+ * fetch progress info instead if background proc still running. */
+{
+char *html = NULL;
 
 // get the pid and see if it is still running
 char pidName[1024];
 safef(pidName, sizeof pidName, "%s.pid", url);
+
+if (waitForBackgroundFile(pidName)) return;
+
 FILE *pidF = mustOpen(pidName, "r");
 long pid = 0;
 fscanf(pidF, "%ld", &pid);
 carefulClose(&pidF);
 
 // If the background process is still running, grab the progress file instead
 if (getpgid(pid) >= 0)
     {
     htmlOpen("Background Status");
     char progressName[1024];
     safef(progressName, sizeof progressName, "%s.progress", url);
+    if (waitForBackgroundFile(progressName)) return;
     if (fileExists(progressName))
 	{
 	readInGulp(progressName, &html, NULL);
 	printf("%s",html);
 	}
     else
 	{
 	printf("progress file missing<br>\n");
 	}
 
     printf("<BR>\n<FORM ACTION=\"/cgi-bin/hgTables\" METHOD=GET>\n"
 	//"<INPUT TYPE=SUBMIT NAME=\"%s\" VALUE=\"Back\" >"
 	"<INPUT TYPE=SUBMIT NAME=\"Refresh\" id='Refresh' VALUE=\"Refresh\">"
 	"</FORM>\n"
 	);
     jsOnEventById("click", "Refresh", "window.location=window.location;return false;");
     jsInline("setTimeout(function(){location = location;},5000);\n");
     jsInline("window.scrollTo(0,document.body.scrollHeight);");
 
     htmlClose();
     return;
     }
 
 // otherwise read the main html file
+// sometimes the background process is a little slow,
+if (waitForBackgroundFile(url)) return;
 
 readInGulp(url, &html, NULL);
 int numLines = chopString(html, "\n", NULL, 1000000);
 char **lines = NULL;
 AllocArray(lines, numLines);
 chopString(html, "\n", lines, numLines);
 int end;
 for (end=numLines-1; end >= 0 && ! (endsWith(lines[end], "</html>") || endsWith(lines[end], "</HTML>")) ; --end)
     /* do nothing */ ;
 if (end < 0)
     {
     htmlOpen("Background Status");
     errAbort("No complete html found");
     htmlClose();
     return;