/**
*
*/
package ecologylab.concurrent;
import java.util.Random;
import ecologylab.net.ParsedURL;
import ecologylab.serialization.ElementState;
import ecologylab.serialization.annotations.simpl_scalar;
import ecologylab.serialization.annotations.simpl_tag;
import ecologylab.serialization.types.element.IMappable;
/**
*
*
* @author andruid
*/
@simpl_tag("site")
public
class BasicSite extends ElementState implements IMappable<String>
{
static Random random = new Random(System.currentTimeMillis());
@simpl_scalar protected String domain;
@simpl_scalar
int numTimeouts;
@simpl_scalar
int numFileNotFounds;
@simpl_scalar
int numOtherIoErrors;
@simpl_scalar
int numNormalDownloads;
protected int downloadsQueuedOrInProgress;
boolean ignore;
long nextAvailableTime;
static final int MAX_TIMEOUTS = 6;
/**
* Minimum time to wait between downloads for this domain
* Specified in seconds
*/
@simpl_scalar protected float minDownloadInterval;
/**
* Timestamp of last download from this site;
*/
long lastDownloadAt;
@simpl_scalar protected boolean ignoreSemanticBoost;
boolean isDownloading;
/**
* Use for XML Translation
*/
public BasicSite()
{
// TODO Auto-generated constructor stub
}
public void countTimeout(ParsedURL location)
{
numTimeouts++;
warning("Timeout " + numTimeouts + "\t" + location);
}
public void countFileNotFound(ParsedURL location)
{
numFileNotFounds++;
warning("FileNotFound " + numFileNotFounds + "\t" + location);
}
public void countOtherIoError(ParsedURL location)
{
numOtherIoErrors++;
warning("Other IO Error " + numOtherIoErrors + "\t" + location);
}
public void countNormalDownload()
{
numNormalDownloads++;
}
public synchronized void queuedDownload()
{
downloadsQueuedOrInProgress++;
}
public synchronized void endDownload()
{
debug("Ending downloading for site");
isDownloading = false;
downloadsQueuedOrInProgress--;
}
public boolean tooManyTimeouts()
{
return numTimeouts >= MAX_TIMEOUTS;
}
public boolean isDown()
{
boolean result = tooManyTimeouts();
if (result)
warning("Cancelling because " + numTimeouts + " timeouts");
return result;
}
/**
*
* @return (numTimeouts == 0) ? 1 : 1.0 / (numTimeouts + 1);
*/
public double timeoutsFactor()
{
return (numTimeouts == 0) ? 1 : 1.0 / (numTimeouts + 1);
}
/**
* @return the minDownloadInterval
*/
public float getMinDownloadInterval()
{
return minDownloadInterval;
}
/**
* @param minDownloadInterval the minDownloadInterval to set
*/
public void setMinDownloadInterval(float minDownloadInterval)
{
this.minDownloadInterval = minDownloadInterval;
}
/**
* @return the lastDownloadAt
*/
public long getLastDownloadAt()
{
return lastDownloadAt;
}
/**
* Register that we are down loading, and the current time as when the down load started.
*/
public void beginActualDownload()
{
this.isDownloading = true;
this.lastDownloadAt = System.currentTimeMillis();
}
/**
* Swing delays between downloads for a site by a large margin.
* @return time in millis
*/
public long getDecentDownloadInterval()
{
int millis = (int) (minDownloadInterval * 1000);
return millis + random.nextInt(millis / 2);
}
public boolean constrainDownloadInterval()
{
return minDownloadInterval > 0;
}
@Override
public String key()
{
return domain;
}
/**
*
*
* @return the isDownloading
*/
public boolean isDownloading()
{
return isDownloading;
}
/**
* Call this when a download to a site was actually fulfilled by a local copy.
*/
public void resetLastDownloadAt()
{
this.lastDownloadAt = 0;
}
public String domain()
{
return domain;
}
public boolean ignoreSemanticBoost()
{
return ignoreSemanticBoost;
}
public boolean shouldIgnore()
{
return ignore;
}
/**
* Recycle and Mark this site as recycled.
*
*/
public void setIgnored(boolean ignore)
{
this.ignore = ignore;
}
public long getNextAvailableTime()
{
return nextAvailableTime;
}
void advanceNextAvailableTime()
{
this.nextAvailableTime = System.currentTimeMillis() + getDecentDownloadInterval();
}
private static final int TWELVE_HOURS_IN_MILLIS = 1000*60*60*12;
public void setAbnormallyLongNextAvailableTime()
{
this.nextAvailableTime = System.currentTimeMillis() + TWELVE_HOURS_IN_MILLIS;
}
}