Index: src/java/org/apache/nutch/searcher/DistributedSearch.java
===================================================================
--- src/java/org/apache/nutch/searcher/DistributedSearch.java	(revision 160184)
+++ src/java/org/apache/nutch/searcher/DistributedSearch.java	(working copy)
@@ -283,11 +283,31 @@
 
   /** The search client. */
   public static class Client extends org.apache.nutch.ipc.Client
-    implements Searcher, HitDetailer, HitSummarizer, HitContent {
+    implements Searcher, HitDetailer, HitSummarizer, HitContent, Runnable {
 
-    private InetSocketAddress[] addresses;
+    private InetSocketAddress[] addresses=new InetSocketAddress[0];
+    private InetSocketAddress[] defaultaddresses;
     private HashMap segmentToAddress = new HashMap();
+    
+    /**
+     * Flag for watchdog, true=keep running, false=stop
+     */
+    private boolean shouldrun=true;
 
+    /**
+     * Backgroudthread that gets polling search servers.
+     */
+    private Thread watchdog;
+    /**
+     * Statistics about online search servers
+     */
+    private int stat_servers;
+    
+    /**
+     * statistics about online segments
+     */
+    private int stat_segments;
+
     /** Construct a client talking to servers listed in the named file.
      * Each line in the file lists a server hostname and port, separated by
      * whitespace. 
@@ -320,29 +340,52 @@
     /** Construct a client talking to the named servers. */
     public Client(InetSocketAddress[] addresses) throws IOException {
       super(Result.class);
+      this.defaultaddresses = addresses;
+      watchdog=new Thread(this);
+      watchdog.start();
+    }
+    
+    /** Updates segments
+     * 
+     * @throws IOException
+     */
+    public void updateSegments() throws IOException {
       
-      this.addresses = addresses;
-
+      stat_servers=0;
+      stat_segments=0;
+      
+      Vector aliveaddresses=new Vector();
+      
       // build segmentToAddress map
       Param param = new Param(OP_SEGMENTS, NullWritable.get());
-      Writable[] params = new Writable[addresses.length];
+      Writable[] params = new Writable[defaultaddresses.length];
       for (int i = 0; i < params.length; i++) {
         params[i] = param;                     // build param for parallel call
       }
-      Writable[] results = call(params, addresses); // make parallel call
+      Writable[] results = call(params, defaultaddresses); // make parallel call
 
       for (int i = 0; i < results.length; i++) {  // process results of call
         Result result = (Result)results[i];
         if (result == null) {
-          LOG.warning("Client: no segments from: " + addresses[i]);
+          LOG.warning("Client: no segments from: " + defaultaddresses[i]);
           continue;
         }
         String[] segments = ((ArrayWritable)result.value).toStrings();
         for (int j = 0; j < segments.length; j++) {
-          LOG.info("Client: segment "+segments[j]+" at "+addresses[i]);
-          segmentToAddress.put(segments[j], addresses[i]);
+          LOG.info("Client: segment "+segments[j]+" at "+defaultaddresses[i]);
+          segmentToAddress.put(segments[j], defaultaddresses[i]);
+          aliveaddresses.add(defaultaddresses[i]);
         }
+        stat_servers++;
+        stat_segments+=segments.length;
       }
+      InetSocketAddress tmpaddresses[]=new InetSocketAddress[aliveaddresses.size()];
+      Iterator addriterator=aliveaddresses.iterator();
+      int index=0;
+      while(addriterator.hasNext()){
+        tmpaddresses[index++]=(InetSocketAddress)addriterator.next();
+      }
+      this.addresses=tmpaddresses;
     }
 
     /** Return the names of segments searched. */
@@ -504,7 +547,32 @@
 
     }
 
-
+    public void run() {
+      while (shouldrun=true){
+        try{
+          LOG.info("Querying segments from search servers");
+          updateSegments();
+          LOG.info("STATS: " + stat_servers + " servers / " + stat_segments + " segments online.");
+        } catch (IOException ioe) {
+          LOG.warning("No search servers available!");
+          addresses=new InetSocketAddress[0];
+        }
+        try{
+          Thread.sleep(10000);
+        } catch (InterruptedException ie){
+          LOG.info("Thread sleep interrupted.");
+        }
+      }
+    }
+    
+    /**
+     * Stops the watchdog thread.
+     *
+     */
+    public void setStop(){
+      LOG.info("stopping watchdog.");
+      shouldrun=false;
+      watchdog.interrupt();
+    }
   }
-
 }
Index: src/web/jsp/search.jsp
===================================================================
--- src/web/jsp/search.jsp	(revision 160184)
+++ src/web/jsp/search.jsp	(working copy)
@@ -150,7 +150,12 @@
     // NOTE by Dawid Weiss:
     // The 'clustering' window actually moves with the start
     // position.... this is good, bad?... ugly?....
-   Hits hits = bean.search(query, start + hitsToRetrieve, hitsPerSite);
+   Hits hits;
+   try{
+     hits = bean.search(query, start + hitsToRetrieve, hitsPerSite);
+   } catch (IOException e){
+     hits = new Hits(0,new Hit[0]);	
+   }
    int end = (int)Math.min(hits.getLength(), start + hitsPerPage);
    int length = end-start;
    int realEnd = (int)Math.min(hits.getLength(), start + hitsToRetrieve);
@@ -260,7 +265,6 @@
 <%
     }
 %>
-
 <p>
 <a href="http://www.nutch.org/">
 <img border="0" src="../img/poweredbynutch_01.gif">
