commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thoralf Rickert <thor...@m84.de>
Subject Re: HTTPClient Feature Patch
Date Sun, 23 Feb 2003 09:52:18 GMT
Hi!

> I would recommend against doing it in this way.  Primarily because it 
> involves polling (the second thread calling getWrittenRequestBodyBytes() 
> repeatedly) and because of the added synchronization overhead.

Yes, I would call it just once a second, but nobody knows what someone 
else does.

> In my experience it is easier and more reusable to handle this at the 
> InputStream level.  This involves adding a wrapper class around the 
> InputStream that is being put/posted.  It would look something like:
> 
> class ProgressInputStream extends FilterInputStream {
 > [...]

So, maybe I don't need a code change in the class EntityEnclosingMethod, 
because I could use the ProgressInputStream instead of a simple 
InputStream in the method
     EntityEnclosingMethod#setRequestBody(InputStream body)
But what about the #setRequestBody(String body) method. OK, I could use a
     ProgressInputStream(new ByteArrayInputStream(body.getBytes()))
as the body.

But especially for my actual problem (the WebDAV client progressbar), I 
don't have (real) access to the Source code and the above changes in the 
httpclient must be added in every implementation that uses the 
#setRequestBody() method.
I think, it would be easier and better to implement a "ProgressObserver" 
at the lowest possible position. To avoid waste of resources, it could 
be possible to add ProgressListener directly to the 
EntityEnclosingMethod. Example:

public abstract class EntityEnclosingMethod extends GetMethod {
   [...]
   private List progressListeners = new ArrayList();
   [...]
   public void addProgressListener(ProgressListener listener) {
     progressListeners.add(listener);
   }

   public List getProgressListeners() { return progressListeners; }

   protected boolean writeRequestBody(
       HttpState state, HttpConnection conn) {
     //...
     if (progressListeners.isEmpty()) {
       InputStream instream = getRequestBody();
     } else {
       InputStream instream = new ProgressInputStream(
                                    getRequestBody(),
                                    getProgressListeners());
     }
     // ...
}

public class ProgressInputStream extends FilterInputStream {
   // ...
   public ProgressInputStream(InputStream is, List progressListeners) {
     //...
   }
   // ...
   private void bytesRead(int count) {
     bytesRead+=count;
     if (progressListeners==null || progressListeners.isEmpty()) return;
     for (int i=0; i<progressListeners.size();i++) {
       ProgressListener l = (ProgressListener)progressListeners.get(i);
       if (bytesRead > l.getThreshold()) {
         totalBytesRead += bytesRead;
         bytesRead = 0;
         l.progressAchieved(totalBytesRead);
       }
     }
   }
}

The EVENT_THRESHOLD value should be part of the ProgressListener, should 
be "setable" and should be checked by the ProgressInputStream. 
(Different values MUST be possible, for example transfering data over a 
slow connection should show the transfer of even 10 Bytes).

public Interface ProgressListener {
   public void progressAchieved(long totalBytesRead);
   public int getThreshold();
}


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message