package org.dcache.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import diskCacheV111.util.CacheException;
/**
* Task that queries the pools for a set of movers. Will eventually
* terminate a transfer if the mover is missing or does not respond.
*/
public class PingMoversTask<T extends Transfer> implements Runnable
{
private static final Logger _log =
LoggerFactory.getLogger(PingMoversTask.class);
private final Collection<T> _transfers;
/**
* Movers which we tried to ping, but we failed to locate on
* the pool.
*/
private Set<Transfer> _missing = new HashSet<>();
/**
* Constructs a PingMoverTask for a set of transfers. The set is
* supposed to be live in the sense that it always represents the
* current set of transfers to monitor. The set must be thread
* safe.
*/
public PingMoversTask(Collection<T> transfers)
{
_transfers = transfers;
}
@Override
public void run()
{
try {
Set<Transfer> missingLastTime = _missing;
_missing = new HashSet<>();
for (Transfer transfer: _transfers) {
try {
if (transfer.hasMover()) {
transfer.queryMoverInfo();
_log.debug("Mover {}/{} is alive",
transfer.getPool(), transfer.getMoverId());
}
} catch (IllegalStateException e) {
// The transfer terminated before we could query it.
_log.debug(e.toString());
} catch (CacheException e) {
_log.info("Failed to check status of mover {}/{}: {}", transfer.getPool(), transfer.getMoverId(),
e.getMessage());
if (missingLastTime.contains(transfer)) {
transfer.finished(CacheException.TIMEOUT,
String.format("Transfer killed by door due to failure for mover %s/%d: %s",
transfer.getPool(),
transfer.getMoverId(),
e.getMessage()));
} else {
_missing.add(transfer);
}
}
}
} catch (InterruptedException e) {
}
}
}