36f8f6fb024b20cc523cdf9ebde7491eca84fd7c
markd
  Sun Dec 6 20:33:20 2020 -0800
multiple request per connect works except hgBlat

diff --git src/jkOwnLib/gfBlatLib.c src/jkOwnLib/gfBlatLib.c
index d3d9cdd..2a6010d 100644
--- src/jkOwnLib/gfBlatLib.c
+++ src/jkOwnLib/gfBlatLib.c
@@ -97,90 +97,88 @@
     else
        diff = 0;
 #ifdef SOLARIS_WORKAROUND_COMPILER_BUG_BUT_FAILS_IN_64_BIT
     diff = (unsigned long)(a->t3) - (unsigned long)(b->t3);	/* Casts needed for Solaris.  Thanks Darren Platt! */
 #endif /* SOLARIS_WORKAROUND_COMPILER_BUG_BUT_FAILS_IN_64_BIT */
     }
 if (diff == 0)
     diff = a->tStart - b->tStart;
 return diff;
 }
 
 static void startSeqQuery(struct gfConnection *conn, bioSeq *seq, char *type, char *genome, char *genomeDataDir)
 /* Send a query that involves some sequence. */
 {
 char buf[1024]; // room for error message if we need it.
-safef(buf, sizeof(buf), "%s%s %d", gfSignature(), type, seq->size);
+safef(buf, sizeof(buf), "%s%s", gfSignature(), type);
 if (genomeDataDir != NULL)
-    {
-    safecat(buf, sizeof(buf), " ");
-    safecat(buf, sizeof(buf), genome);
-    safecat(buf, sizeof(buf), " ");
-    safecat(buf, sizeof(buf), genomeDataDir);
-    }
+    safefcat(buf, sizeof(buf), " %s %s", genome, genomeDataDir);
+safefcat(buf, sizeof(buf), " %d", seq->size);
 mustWriteFd(conn->fd, buf, strlen(buf));
 if (read(conn->fd, buf, 1) < 0)
     errAbort("startSeqQuery: read failed: %s", strerror(errno));
 if (buf[0] != 'Y')
     {
     // try to get read of message, might be an a useful error
     int n = read(conn->fd, buf+1, sizeof(buf)-2);
     if (n >= 0)
         buf[n+1] = '\0';
     errAbort("Expecting 'Y' from server, got %s", buf);
     }
 mustWriteFd(conn->fd, seq->dna, seq->size);
 }
 
 static void gfServerWarn(bioSeq *seq, char *warning)
 /* Write out warning. */
 {
 warn("couldn't process %s: %s", seq->name, warning);
 }
 
 static struct gfRange *gfQuerySeq(struct gfConnection *conn, struct dnaSeq *seq, char *genome, char *genomeDataDir)
 /* Ask server for places sequence hits. */
 {
 struct gfRange *rangeList = NULL, *range;
 char buf[256], *row[6];
 int rowSize;
 
+gfBeginRequest(conn);
 startSeqQuery(conn, seq, "query", genome, genomeDataDir);
 
 /* Read results line by line and save in list, and return. */
 for (;;)
     {
     netRecieveString(conn->fd, buf);
     if (sameString(buf, "end"))
 	{
 	break;
 	}
     else if (startsWith("Error:", buf))
         {
 	gfServerWarn(seq, buf);
 	break;
 	}
     else
 	{
 	rowSize = chopLine(buf, row);
 	if (rowSize < 6)
 	    errAbort("Expecting 6 words from server got %d", rowSize);
 	range = gfRangeLoad(row);
 	slAddHead(&rangeList, range);
 	}
     }
 slReverse(&rangeList);
+gfEndRequest(conn);
 return rangeList;
 }
 
 static int findTileSize(char *line)
 /* Parse through line/val pairs looking for tileSize. */
 {
 char *var, *val;
 int tileSize = 4;
 for (;;)
     {
     var = nextWord(&line);
     if (var == NULL)
          break;
     val = nextWord(&line);
     if (val == NULL)
@@ -225,30 +223,31 @@
                             char *genome, char *genomeDataDir)
 /* Query server for clumps where aa sequence hits translated index. */
 {
 int frame, isRc, rowSize;
 struct gfClump *clump;
 int tileSize = 0;
 char *line;
 char buf[256], *row[12];
 struct gfSeqSource *ssList = NULL, *ss;
 
 for (isRc = 0; isRc <= 1; ++isRc)
     for (frame = 0; frame<3; ++frame)
 	clumps[isRc][frame] = NULL;
 
 /* Send sequence to server. */
+gfBeginRequest(conn);
 startSeqQuery(conn, seq, "protQuery", genome, genomeDataDir);
 line = netRecieveString(conn->fd, buf);
 if (!startsWith("Error:", line))
     {
     tileSize = findTileSize(line);
 
     /* Read results line by line and save in memory. */
     for (;;)
 	{
 	/* Read and parse first line that describes clump overall. */
 	netRecieveString(conn->fd, buf);
 	if (sameString(buf, "end"))
 	    {
 	    break;
 	    }
@@ -274,54 +273,56 @@
 	frame = sqlUnsigned(row[7]);
 	slAddHead(&clumps[isRc][frame], clump);
 
 	/* Read and parse next (long) line that describes hits. */
 	clump->hitList = getHitsFromServer(conn, lm);
 	assert(slCount(clump->hitList) == clump->hitCount);
 	}
     for (isRc = 0; isRc <= 1; ++isRc)
 	for (frame = 0; frame<3; ++frame)
 	    slReverse(&clumps[isRc][frame]);
     }
 else
     {
     gfServerWarn(seq, line);
     }
+gfEndRequest(conn);
 *retSsList = ssList;
 *retTileSize = tileSize;
 }
 
 static void gfQuerySeqTransTrans(struct gfConnection *conn, struct dnaSeq *seq, 
                                  struct gfClump *clumps[2][3][3], 
                                  struct lm *lm, struct gfSeqSource **retSsList, int *retTileSize,
                                  char *genome, char *genomeDataDir)
 /* Query server for clumps where translated DNA sequence hits translated 
  * index. */
 {
 int qFrame, tFrame, isRc, rowSize;
 struct gfClump *clump;
 int tileSize = 0;
 char *line;
 char buf[256], *row[12];
 struct gfSeqSource *ssList = NULL, *ss;
 
 for (isRc = 0; isRc <= 1; ++isRc)
     for (qFrame = 0; qFrame<3; ++qFrame)
 	for (tFrame = 0; tFrame<3; ++tFrame)
 	    clumps[isRc][qFrame][tFrame] = NULL;
 
 /* Send sequence to server. */
+gfBeginRequest(conn);
 startSeqQuery(conn, seq, "transQuery", genome, genomeDataDir);
 line = netRecieveString(conn->fd, buf);
 if (!startsWith("Error:", line))
     {
     tileSize = findTileSize(line);
 
     /* Read results line by line and save in memory. */
     for (;;)
 	{
 	/* Read and parse first line that describes clump overall. */
 	netRecieveString(conn->fd, buf);
 	if (sameString(buf, "end"))
 	    {
 	    break;
 	    }
@@ -349,30 +350,31 @@
 	slAddHead(&clumps[isRc][qFrame][tFrame], clump);
 
 	/* Read and parse next (long) line that describes hits. */
 	clump->hitList = getHitsFromServer(conn, lm);
 	assert(slCount(clump->hitList) == clump->hitCount);
 	}
     for (isRc = 0; isRc <= 1; ++isRc)
 	for (qFrame = 0; qFrame<3; ++qFrame)
 	    for (tFrame = 0; tFrame<3; ++tFrame)
 		slReverse(&clumps[isRc][qFrame][tFrame]);
     }
 else
     {
     gfServerWarn(seq, buf);
     }
+gfEndRequest(conn);
 *retSsList = ssList;
 *retTileSize = tileSize;
 }
 
 
 
 struct gfRange *gfRangesBundle(struct gfRange *exonList, int maxIntron)
 /* Bundle a bunch of 'exons' into plausable 'genes'.  It's
  * not necessary to be precise here.  The main thing is to
  * group together exons that are close to each other in the
  * same target sequence. */
 {
 struct gfRange *geneList = NULL, *gene = NULL, *lastExon = NULL, *exon, *nextExon;
 
 for (exon = exonList; exon != NULL; exon = nextExon)
@@ -1061,32 +1063,30 @@
 struct ssBundle *bun;
 struct gfClump *clumps[2][3], *clump;
 struct gfRange *rangeList = NULL, *range, *rl;
 struct dnaSeq *targetSeq, *tSeqList = NULL;
 char targetName[PATH_LEN];
 int tileSize;
 int frame, isRc = 0;
 struct hash *t3Hash = NULL;
 struct slRef *t3RefList = NULL, *ref;
 struct gfSeqSource *ssList = NULL, *ss;
 struct trans3 *t3;
 struct lm *lm = lmInit(0);
 
 /* Get clumps from server. */
 gfQuerySeqTrans(conn, seq, clumps, lm, &ssList, &tileSize, genome, genomeDataDir);
-close(conn->fd);
-conn->fd = -1;
 
 for (isRc = 0; isRc <= 1;  ++isRc)
     {
     /* Figure out which parts of sequence we need to load. */
     for (frame = 0; frame < 3; ++frame)
 	{
 	rl = seqClumpToRangeList(clumps[isRc][frame], frame);
 	rangeList = slCat(rangeList, rl);
 	}
     /* Convert from amino acid to nucleotide coordinates. */
     rangeCoorTimes3(rangeList);
     slSort(&rangeList, gfRangeCmpTarget);
     rangeList = gfRangesBundle(rangeList, ffIntronMax);
     loadHashT3Ranges(rangeList, tSeqDir, tFileCache, seq->size, 
     	isRc, &t3Hash, &tSeqList, &t3RefList);
@@ -1185,32 +1185,30 @@
 struct gfClump *clumps[2][3][3], *clump;
 char targetName[PATH_LEN];
 int qFrame, tFrame, tIsRc;
 struct gfSeqSource *ssList = NULL, *ss;
 struct lm *lm = lmInit(0);
 int tileSize;
 struct gfRange *rangeList = NULL, *rl, *range;
 struct trans3 *qTrans = trans3New(qSeq), *t3;
 struct slRef *t3RefList = NULL, *t3Ref;
 struct hash *t3Hash = NULL;
 struct dnaSeq *tSeqList = NULL;
 enum ffStringency stringency = (isRna ? ffCdna : ffLoose);
 
 /* Query server for clumps. */
 gfQuerySeqTransTrans(conn, qSeq, clumps, lm, &ssList, &tileSize, genome, genomeDataDir);
-close(conn->fd);
-conn->fd = -1;
 
 for (tIsRc=0; tIsRc <= 1; ++tIsRc)
     {
     /* Figure out which ranges need to be loaded and load them. */
     for (qFrame = 0; qFrame < 3; ++qFrame)
         {
         for (tFrame = 0; tFrame < 3; ++tFrame)
             {
 	    rl = seqClumpToRangeList(clumps[tIsRc][qFrame][tFrame], tFrame);
 	    rangeList = slCat(rangeList, rl);
 	    }
 	}
     rangeCoorTimes3(rangeList);
     slSort(&rangeList, gfRangeCmpTarget);
     rangeList = gfRangesBundle(rangeList, ffIntronMax);