[tor-commits] [doctor/master] Remember fetch times when requesting consensuses.

karsten at torproject.org karsten at torproject.org
Thu Dec 8 11:56:09 UTC 2011


commit 98b595e62dc63053360dc2a99504b36779e1f253
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Thu Dec 8 11:32:32 2011 +0100

    Remember fetch times when requesting consensuses.
---
 src/org/torproject/doctor/Download.java   |   38 +++++++++++++++
 src/org/torproject/doctor/Downloader.java |   73 +++++++++++++++--------------
 src/org/torproject/doctor/Main.java       |    4 +-
 src/org/torproject/doctor/Parser.java     |   23 ++++++----
 src/org/torproject/doctor/Status.java     |    9 ++++
 5 files changed, 101 insertions(+), 46 deletions(-)

diff --git a/src/org/torproject/doctor/Download.java b/src/org/torproject/doctor/Download.java
new file mode 100644
index 0000000..35c24f9
--- /dev/null
+++ b/src/org/torproject/doctor/Download.java
@@ -0,0 +1,38 @@
+/* Copyright 2011 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.doctor;
+
+public class Download {
+
+  /* Nickname of the authority from which this download was made. */
+  private String authority;
+  public String getAuthority() {
+    return this.authority;
+  }
+
+  /* Request URL. */
+  private String url;
+  public String getUrl() {
+    return this.url;
+  }
+
+  /* Unparsed response string. */
+  private String responseString;
+  public String getResponseString() {
+    return this.responseString;
+  }
+
+  /* Fetch time in millis. */
+  private long fetchTime;
+  public long getFetchTime() {
+    return this.fetchTime;
+  }
+
+  public Download(String authority, String url, String responseString,
+      long fetchTime) {
+    this.authority = authority;
+    this.responseString = responseString;
+    this.fetchTime = fetchTime;
+  }
+}
+
diff --git a/src/org/torproject/doctor/Downloader.java b/src/org/torproject/doctor/Downloader.java
index 3125062..c929a96 100755
--- a/src/org/torproject/doctor/Downloader.java
+++ b/src/org/torproject/doctor/Downloader.java
@@ -37,8 +37,8 @@ public class Downloader {
   }
 
   /* Download the most recent consensus from all authorities. */
-  private SortedMap<String, String> downloadedConsensuses =
-      new TreeMap<String, String>();
+  private List<Download> downloadedConsensuses =
+      new ArrayList<Download>();
   private void downloadConsensus() {
     Map<String, String> urls = new HashMap<String, String>();
     for (Map.Entry<String, String> e : this.authorities.entrySet()) {
@@ -46,19 +46,10 @@ public class Downloader {
       String address = e.getValue();
       String resource = "/tor/status-vote/current/consensus.z";
       String fullUrl = "http://" + address + resource;
-      urls.put(nickname, fullUrl);
-    }
-    Map<String, String> responses =
-        this.downloadFromAuthority(new HashSet<String>(urls.values()));
-    for (Map.Entry<String, String> e : urls.entrySet()) {
-      String nickname = e.getKey();
-      String url = e.getValue();
-      if (responses.containsKey(url)) {
-        String response = responses.get(url);
-        this.downloadedConsensuses.put(nickname, response);
-      }
+      urls.put(fullUrl, nickname);
     }
-    if (responses.isEmpty()) {
+    this.downloadedConsensuses = this.downloadFromAuthority(urls);
+    if (this.downloadedConsensuses.isEmpty()) {
       System.err.println("Could not download consensus from any of the "
           + "directory authorities.  Ignoring.");
     }
@@ -68,14 +59,18 @@ public class Downloader {
    * interrupted after a timeout. */
   private static class DownloadRunnable implements Runnable {
     Thread mainThread;
+    String nickname;
     String url;
     String response;
     boolean finished = false;
-    public DownloadRunnable(String url) {
+    long requestStart = 0L, requestEnd = 0L;
+    public DownloadRunnable(String nickname, String url) {
       this.mainThread = Thread.currentThread();
+      this.nickname = nickname;
       this.url = url;
     }
     public void run() {
+      this.requestStart = System.currentTimeMillis();
       try {
         URL u = new URL(this.url);
         HttpURLConnection huc = (HttpURLConnection) u.openConnection();
@@ -105,16 +100,28 @@ public class Downloader {
         /* Can't do much except leaving this.response at null. */
       }
       this.finished = true;
+      this.requestEnd = System.currentTimeMillis();
+    }
+    public Download getDownload() {
+      Download result = null;
+      if (this.response != null) {
+        result = new Download(this.nickname, this.url, this.response,
+          this.requestEnd - this.requestStart);
+      }
+      return result;
     }
   }
 
   /* Download one or more consensuses or votes from one or more directory
    * authorities using a timeout of 60 seconds. */
-  private Map<String, String> downloadFromAuthority(Set<String> urls) {
+  private List<Download> downloadFromAuthority(Map<String, String> urls) {
     Set<DownloadRunnable> downloadRunnables =
         new HashSet<DownloadRunnable>();
-    for (String url : urls) {
-      DownloadRunnable downloadRunnable = new DownloadRunnable(url);
+    for (Map.Entry<String, String> e : urls.entrySet()) {
+      String url = e.getKey();
+      String nickname = e.getValue();
+      DownloadRunnable downloadRunnable = new DownloadRunnable(nickname,
+          url);
       downloadRunnables.add(downloadRunnable);
       new Thread(downloadRunnable).start();
     }
@@ -137,12 +144,11 @@ public class Downloader {
         break;
       }
     }
-    Map<String, String> responses = new HashMap<String, String>();
+    List<Download> responses = new ArrayList<Download>();
     for (DownloadRunnable downloadRunnable : downloadRunnables) {
-      String url = downloadRunnable.url;
-      String response = downloadRunnable.response;
-      if (response != null) {
-        responses.put(url, response);
+      Download download = downloadRunnable.getDownload();
+      if (download != null) {
+        responses.add(download);
       }
       downloadRunnable.finished = true;
     }
@@ -160,8 +166,8 @@ public class Downloader {
    * authorities publishing the corresponding votes. */
   private SortedSet<String> fingerprints = new TreeSet<String>();
   private void parseConsensusToFindReferencedVotes() {
-    for (String downloadedConsensus :
-        this.downloadedConsensuses.values()) {
+    for (Download download : this.downloadedConsensuses) {
+      String downloadedConsensus = download.getResponseString();
       try {
         BufferedReader br = new BufferedReader(new StringReader(
             downloadedConsensus));
@@ -208,7 +214,7 @@ public class Downloader {
 
   /* Download the votes published by directory authorities listed in the
    * consensus. */
-  private List<String> downloadedVotes = new ArrayList<String>();
+  private List<Download> downloadedVotes = new ArrayList<Download>();
   private void downloadReferencedVotes() {
     for (String fingerprint : this.fingerprints) {
       String downloadedVote = null;
@@ -222,26 +228,21 @@ public class Downloader {
         String resource = "/tor/status-vote/current/" + fingerprint
             + ".z";
         String fullUrl = "http://" + authority + resource;
-        Set<String> urls = new HashSet<String>();
-        urls.add(fullUrl);
-        Map<String, String> downloadedVotes =
-            this.downloadFromAuthority(urls);
-        if (downloadedVotes.containsKey(fullUrl)) {
-          downloadedVote = downloadedVotes.get(fullUrl);
-          this.downloadedVotes.add(downloadedVote);
-        }
+        Map<String, String> urls = new HashMap<String, String>();
+        urls.put(fullUrl, authority);
+        this.downloadedVotes = this.downloadFromAuthority(urls);
       }
     }
   }
 
   /* Return the previously downloaded (unparsed) consensus string by
    * authority nickname. */
-  public SortedMap<String, String> getConsensusStrings() {
+  public List<Download> getConsensuses() {
     return this.downloadedConsensuses;
   }
 
   /* Return the previously downloaded (unparsed) vote strings. */
-  public List<String> getVoteStrings() {
+  public List<Download> getVotes() {
     return this.downloadedVotes;
   }
 }
diff --git a/src/org/torproject/doctor/Main.java b/src/org/torproject/doctor/Main.java
index 47f3f0b..ec160e9 100755
--- a/src/org/torproject/doctor/Main.java
+++ b/src/org/torproject/doctor/Main.java
@@ -19,11 +19,13 @@ public class Main {
      * authorities. */
     Downloader downloader = new Downloader();
     downloader.downloadFromAuthorities();
+    List<Download> downloadedConsensuses = downloader.getConsensuses();
+    List<Download> downloadedVotes = downloader.getVotes();
 
     /* Parse consensus and votes. */
     Parser parser = new Parser();
     SortedMap<String, Status> parsedDownloadedConsensuses = parser.parse(
-        downloader.getConsensusStrings(), downloader.getVoteStrings());
+        downloadedConsensuses, downloadedVotes);
 
     /* Check consensus and votes for possible problems. */
     Checker checker = new Checker();
diff --git a/src/org/torproject/doctor/Parser.java b/src/org/torproject/doctor/Parser.java
index 36abd78..9a91033 100755
--- a/src/org/torproject/doctor/Parser.java
+++ b/src/org/torproject/doctor/Parser.java
@@ -13,22 +13,26 @@ public class Parser {
   /* Parse and return a consensus and corresponding votes, or null if
    * something goes wrong. */
   public SortedMap<String, Status> parse(
-      SortedMap<String, String> consensusStrings,
-      List<String> voteStrings) {
+      List<Download> downloadedConsensuses,
+      List<Download> downloadedVotes) {
     SortedSet<Status> parsedVotes = new TreeSet<Status>();
-    for (String voteString : voteStrings) {
-      Status parsedVote = this.parseConsensusOrVote(voteString, false);
+    for (Download downloadedVote : downloadedVotes) {
+      String voteString = downloadedVote.getResponseString();
+      long fetchTime = downloadedVote.getFetchTime();
+      Status parsedVote = this.parseConsensusOrVote(voteString, fetchTime,
+          false);
       if (parsedVote != null) {
         parsedVotes.add(parsedVote);
       }
     }
     SortedMap<String, Status> parsedConsensuses =
         new TreeMap<String, Status>();
-    for (Map.Entry<String, String> e : consensusStrings.entrySet()) {
-      String nickname = e.getKey();
-      String consensusString = e.getValue();
+    for (Download downloadedConsensus : downloadedConsensuses) {
+      String nickname = downloadedConsensus.getAuthority();
+      String consensusString = downloadedConsensus.getResponseString();
+      long fetchTime = downloadedConsensus.getFetchTime();
       Status parsedConsensus = this.parseConsensusOrVote(consensusString,
-          true);
+          fetchTime, true);
       if (parsedConsensus != null) {
         for (Status parsedVote : parsedVotes) {
           if (parsedConsensus.getValidAfterMillis() ==
@@ -50,13 +54,14 @@ public class Parser {
   }
 
   /* Parse a consensus or vote string into a Status instance. */
-  private Status parseConsensusOrVote(String statusString,
+  private Status parseConsensusOrVote(String statusString, long fetchTime,
       boolean isConsensus) {
     if (statusString == null) {
       return null;
     }
     Status status = new Status();
     status.setUnparsedString(statusString);
+    status.setFetchTime(fetchTime);
     try {
       BufferedReader br = new BufferedReader(new StringReader(
           statusString));
diff --git a/src/org/torproject/doctor/Status.java b/src/org/torproject/doctor/Status.java
index 40a7225..0573ae2 100755
--- a/src/org/torproject/doctor/Status.java
+++ b/src/org/torproject/doctor/Status.java
@@ -29,6 +29,15 @@ public class Status implements Comparable<Status> {
     return this.unparsedString;
   }
 
+  /* Fetch time in millis. */
+  private long fetchTime;
+  public void setFetchTime(long fetchTime) {
+    this.fetchTime = fetchTime;
+  }
+  public long getFetchTime() {
+    return this.fetchTime;
+  }
+
   /* Votes published at the same time as this consensus; votes don't
    * reference any statuses. */
   private SortedSet<Status> votes = new TreeSet<Status>();





More information about the tor-commits mailing list