提交 0072bda2 编写于 作者: S stephenconnolly

adding utility methods to allow querying how long a computer has been idle

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@9442 71c3de6d-444a-0410-be80-ed276b4c234a
上级 a499c320
......@@ -269,6 +269,17 @@ public abstract class Computer extends AbstractModelObject {
return true;
}
/**
* Returns the time when this computer first became idle.
*/
public final long getIdleStartMilliseconds() {
long firstIdle = Long.MIN_VALUE;
for (Executor e : executors) {
firstIdle = Math.max(firstIdle, e.getIdleStartMilliseconds());
}
return firstIdle;
}
/**
* Called by {@link Executor} to kill excessive executors from this computer.
*/
......
......@@ -22,6 +22,10 @@ public class Executor extends Thread implements ModelObject {
private final Queue queue;
private long startTime;
/**
* Used to track when a job was last executed.
*/
private long finishTime;
/**
* Executor number that identifies it among other executors for the same {@link Computer}.
......@@ -47,6 +51,7 @@ public class Executor extends Thread implements ModelObject {
SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
try {
finishTime = System.currentTimeMillis();
while(true) {
if(Hudson.getInstance().isTerminating())
return;
......@@ -81,6 +86,7 @@ public class Executor extends Thread implements ModelObject {
// so just leave some info and go on to build other things
LOGGER.log(Level.SEVERE, "Executor throw an exception unexpectedly",e);
}
finishTime = System.currentTimeMillis();
executable = null;
}
} catch(RuntimeException e) {
......@@ -195,6 +201,18 @@ public class Executor extends Thread implements ModelObject {
return owner;
}
/**
* Returns when this executor started or should start being idle.
*/
public long getIdleStartMilliseconds() {
if (isIdle())
return finishTime;
else {
return Math.max(startTime + executable.getParent().getEstimatedDuration(),
System.currentTimeMillis() + 15000);
}
}
/**
* Returns the executor of the current thread.
*/
......
......@@ -117,9 +117,6 @@ public abstract class RetentionStrategy<T extends Computer> implements Describab
*/
private final long idleDelay;
private transient Long finishTransition = null;
private transient Boolean startState = null;
@DataBoundConstructor
public Demand(long inDemandDelay, long idleDelay) {
this.inDemandDelay = inDemandDelay;
......@@ -150,55 +147,31 @@ public abstract class RetentionStrategy<T extends Computer> implements Describab
* {@inheritDoc}
*/
public synchronized long check(SlaveComputer c) {
if (!Boolean.valueOf(c.isOffline()).equals(startState)) {
// reset the timer as we are no longer in the starting state
finishTransition = null;
startState = c.isOffline();
}
if (c.isOffline()) {
final Queue queue = Hudson.getInstance().getQueue();
final Queue.Item[] items = queue.getItems(); // TODO filter this array to this computer
for (Queue.Item item : items) {
if ((System.currentTimeMillis() - item.timestamp.getTimeInMillis()) >
TimeUnit.MILLISECONDS.convert(inDemandDelay, TimeUnit.MINUTES)) {
logger.log(Level.INFO, "Trying to launch computer {0} as it has been in demand for too long", c.getNode().getNodeName());
// we've been in demand for long enough
logger.log(Level.INFO, "Trying to launch computer {0} as it has been in demand for too long", c.getNode().getNodeName());
if (c.isOffline() && c.isLaunchSupported())
c.tryReconnect();
finishTransition = null;
break;
}
}
} else {
if (c.isIdle()) {
if (finishTransition == null) {
logger.log(Level.INFO, "Computer {0} is now idle, {1} minutes until disconnection",
new Object[]{c.getNode().getNodeName(), idleDelay});
// only just noticed that we're idle
finishTransition = System.currentTimeMillis() +
TimeUnit.MILLISECONDS.convert(idleDelay, TimeUnit.MINUTES);
} else if (System.currentTimeMillis() > finishTransition) {
logger.log(Level.INFO, "Disconnecting computer {0} as it has been idle too long", c.getNode().getNodeName());
if (System.currentTimeMillis() - c.getIdleStartMilliseconds() >
TimeUnit.MILLISECONDS.convert(inDemandDelay, TimeUnit.MINUTES)) {
// we've been idle for long enough
logger.log(Level.INFO, "Disconnecting computer {0} as it has been idle too long", c.getNode().getNodeName());
c.disconnect();
finishTransition = null;
} else {
logger.log(Level.INFO, "Computer {0} is still idle, {1} minutes until disconnection",
new Object[]{c.getNode().getNodeName(),
TimeUnit.MILLISECONDS.convert(
Math.max(0, finishTransition - System.currentTimeMillis()),
TimeUnit.MINUTES)
});
}
} else {
// reset our timer
finishTransition = null;
}
return 1;
}
return 0;
return 1;
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册