JAL-3730 retry ping before failing; sysout logging changed to Cache.log feature/JAL-3730ensemblPingRetries
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 31 Aug 2020 09:33:14 +0000 (10:33 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 31 Aug 2020 09:33:14 +0000 (10:33 +0100)
src/jalview/ext/ensembl/EnsemblMap.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java

index cfc679c..16d16d2 100644 (file)
  */
 package jalview.ext.ensembl;
 
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefSource;
-import jalview.datamodel.GeneLociI;
-import jalview.datamodel.GeneLocus;
-import jalview.datamodel.Mapping;
-import jalview.util.MapList;
-
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -38,6 +31,14 @@ import java.util.Map;
 
 import org.json.simple.parser.ParseException;
 
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.GeneLociI;
+import jalview.datamodel.GeneLocus;
+import jalview.datamodel.Mapping;
+import jalview.util.MapList;
+
 /**
  * A client for the Ensembl REST service /map endpoint, to convert from
  * coordinates of one genome assembly to another.
@@ -157,7 +158,7 @@ public class EnsemblMap extends EnsemblRestClient
       return (parseAssemblyMappingResponse(url));
     } catch (Throwable t)
     {
-      System.out.println("Error calling " + url + ": " + t.getMessage());
+      Cache.log.error("Error calling " + url + ": " + t.getMessage());
       return null;
     }
   }
@@ -264,7 +265,7 @@ public class EnsemblMap extends EnsemblRestClient
       return null;
     } catch (Throwable t)
     {
-      System.out.println("Error calling " + url + ": " + t.getMessage());
+      Cache.log.error("Error calling " + url + ": " + t.getMessage());
       return null;
     }
   }
index f75b4b9..e65e7ba 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.ext.ensembl;
 
-import java.io.BufferedReader;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -36,6 +35,7 @@ import javax.ws.rs.HttpMethod;
 
 import org.json.simple.parser.ParseException;
 
+import jalview.bin.Cache;
 import jalview.util.Platform;
 import jalview.util.StringUtils;
 
@@ -46,6 +46,9 @@ import jalview.util.StringUtils;
  */
 abstract class EnsemblRestClient extends EnsemblSequenceFetcher
 {
+  private static final int HTTP_OK = 200;
+
+  private static final int HTTP_OVERLOAD = 429;
 
   static
   {
@@ -53,15 +56,19 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
     Platform.addJ2SDirectDatabaseCall("https://rest.ensembl");
   }
 
-  private static final int DEFAULT_READ_TIMEOUT = 5 * 60 * 1000; // 5 minutes
+  /*
+   * constants for http retries and timeout;
+   * not final so they can be changed by a Groovy script
+   */
+  private static int PING_TIMEOUT_MS = 2 * 1000;
 
-  private static final int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
+  private static long PING_RETEST_INTERVAL = 10 * 1000L; // 10 seconds
 
-  private static final int MAX_RETRIES = 3;
+  private static int DEFAULT_READ_TIMEOUT = 5 * 60 * 1000; // 5 minutes
 
-  private static final int HTTP_OK = 200;
+  private static int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
 
-  private static final int HTTP_OVERLOAD = 429;
+  private static int MAX_RETRIES = 3;
 
   /*
    * update these constants when Jalview has been checked / updated for
@@ -77,8 +84,6 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
 
   private static Map<String, EnsemblData> domainData;
 
-  private final static long AVAILABILITY_RETEST_INTERVAL = 10000L; // 10 seconds
-
   private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
 
   protected static final String CONTENT_TYPE_JSON = "?content-type=application/json";
@@ -187,11 +192,34 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
    * @see http://rest.ensembl.org/documentation/info/ping
    * @return
    */
-  @SuppressWarnings("unchecked")
   boolean checkEnsembl()
   {
-    BufferedReader br = null;
     String pingUrl = getDomain() + "/info/ping" + CONTENT_TYPE_JSON;
+    for (int i = 0 ; i < MAX_RETRIES ; i++)
+    {
+      if (pingEnsembl(pingUrl))
+      {
+        if (i > 0)
+        {
+          Cache.log.info("Ensembl ping responded on attempt " + (i+1));
+        }
+        return true;
+      }
+    }
+    Cache.log.error("Ensembl ping failed after " + MAX_RETRIES + " retries");
+    return false;
+  }
+
+  /**
+   * Connects to Ensembl REST service's 'ping' URL and answers true if
+   * successful, false if no reply, or no reply within the 2 second timeout
+   * 
+   * @param pingUrl
+   * @return
+   */
+  @SuppressWarnings("unchecked")
+  protected boolean pingEnsembl(String pingUrl)
+  {
     try
     {
       // note this format works for both ensembl and ensemblgenomes
@@ -202,7 +230,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
        * if ping takes more than 2 seconds to respond, treat as if unavailable
        */
       Map<String, Object> val = (Map<String, Object>) getJSON(
-              new URL(pingUrl), null, 2 * 1000, MODE_MAP, null);
+              new URL(pingUrl), null, PING_TIMEOUT_MS, MODE_MAP, null);
       if (val == null)
       {
         return false;
@@ -211,22 +239,10 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       return pingString != null;
     } catch (Throwable t)
     {
-      System.err.println(
+      Cache.log.error(
               "Error connecting to " + pingUrl + ": " + t.getMessage());
-    } finally
-    {
-      if (br != null)
-      {
-        try
-        {
-          br.close();
-        } catch (IOException e)
-        {
-          // ignore
-        }
-      }
+      return false;
     }
-    return false;
   }
 
   protected final static int MODE_ARRAY = 0;
@@ -313,7 +329,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
        * note: a GET request for an invalid id returns an error code e.g. 415
        * but POST request returns 200 and an empty Fasta response 
        */
-      System.err.println("Response code " + responseCode);// + " for " + url);
+      Cache.log.error("Response code " + responseCode);// + " for " + url);
       return null;
     }
 
@@ -417,7 +433,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
      * recheck if Ensembl is up if it was down, or the recheck period has elapsed
      */
     boolean retestAvailability = (now
-            - info.lastAvailableCheckTime) > AVAILABILITY_RETEST_INTERVAL;
+            - info.lastAvailableCheckTime) > PING_RETEST_INTERVAL;
     if (!info.restAvailable || retestAvailability)
     {
       info.restAvailable = checkEnsembl();
index fd8800f..fe61a87 100644 (file)
@@ -265,12 +265,12 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     String accId = querySeq.getName();
     try
     {
-      System.out.println("Adding protein product for " + accId);
+      Cache.log.info("Adding protein product for " + accId);
       AlignmentI protein = new EnsemblProtein(getDomain())
               .getSequenceRecords(accId);
       if (protein == null || protein.getHeight() == 0)
       {
-        System.out.println("No protein product found for " + accId);
+        Cache.log.info("No protein product found for " + accId);
         return;
       }
       SequenceI proteinSeq = protein.getSequenceAt(0);
@@ -429,7 +429,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     if (seqs.size() != ids.size())
     {
-      System.out.println(String.format(
+      Cache.log.warn(String.format(
               "Only retrieved %d sequences for %d query strings",
               seqs.size(), ids.size()));
     }
@@ -657,7 +657,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     if (regions.isEmpty())
     {
-      System.out.println("Failed to identify target sequence for " + accId
+      Cache.log.warn("Failed to identify target sequence for " + accId
               + " from genomic features");
       return null;
     }