PageRenderTime 19ms CodeModel.GetById 12ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/hudson-core/src/main/java/hudson/slaves/ConnectionActivityMonitor.java

http://github.com/hudson/hudson
Java | 114 lines | 56 code | 15 blank | 43 comment | 9 complexity | 49694d24d75b55181aea7a8f168c0254 MD5 | raw file
  1/*
  2 * The MIT License
  3 *
  4 * Copyright (c) 2004-2009, Sun Microsystems, Inc.
  5 *
  6 * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 * of this software and associated documentation files (the "Software"), to deal
  8 * in the Software without restriction, including without limitation the rights
  9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10 * copies of the Software, and to permit persons to whom the Software is
 11 * furnished to do so, subject to the following conditions:
 12 *
 13 * The above copyright notice and this permission notice shall be included in
 14 * all copies or substantial portions of the Software.
 15 *
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22 * THE SOFTWARE.
 23 */
 24package hudson.slaves;
 25
 26import hudson.model.AsyncPeriodicWork;
 27import hudson.model.TaskListener;
 28import hudson.model.Hudson;
 29import hudson.model.Computer;
 30import hudson.util.TimeUnit2;
 31import hudson.remoting.VirtualChannel;
 32import hudson.remoting.Channel;
 33import hudson.remoting.Callable;
 34import hudson.Extension;
 35
 36import java.io.IOException;
 37import java.util.logging.Logger;
 38
 39/**
 40 * Makes sure that connections to slaves are alive, and if they are not, cut them off.
 41 *
 42 * <p>
 43 * If we only rely on TCP retransmission time out for this, the time it takes to detect a bad connection
 44 * is in the order of 10s of minutes, so we take the matters to our own hands.
 45 *
 46 * @author Kohsuke Kawaguchi
 47 * @since 1.325
 48 */
 49@Extension
 50public class ConnectionActivityMonitor extends AsyncPeriodicWork {
 51    public ConnectionActivityMonitor() {
 52        super("Connection Activity monitoring to slaves");
 53    }
 54
 55    protected void execute(TaskListener listener) throws IOException, InterruptedException {
 56        if (!enabled)   return;
 57
 58        long now = System.currentTimeMillis();
 59        for (Computer c: Hudson.getInstance().getComputers()) {
 60            VirtualChannel ch = c.getChannel();
 61            if (ch instanceof Channel) {
 62                Channel channel = (Channel) ch;
 63                if (now-channel.getLastHeard() > TIME_TILL_PING) {
 64                    // haven't heard from this slave for a while.
 65                    Long lastPing = (Long)channel.getProperty(ConnectionActivityMonitor.class);
 66
 67                    if (lastPing!=null && now-lastPing > TIMEOUT) {
 68                        LOGGER.info("Repeated ping attempts failed on "+c.getName()+". Disconnecting");
 69                        c.disconnect(OfflineCause.create(Messages._ConnectionActivityMonitor_OfflineCause()));
 70                    } else {
 71                        // send a ping. if we receive a reply, it will be reflected in the next getLastHeard() call.
 72                        channel.callAsync(PING_COMMAND);
 73                        if (lastPing==null)
 74                            channel.setProperty(ConnectionActivityMonitor.class,now);
 75                    }
 76                } else {
 77                    // we are receiving data nicely
 78                    channel.setProperty(ConnectionActivityMonitor.class,null);
 79                }
 80            }
 81        }
 82    }
 83
 84    public long getRecurrencePeriod() {
 85        return enabled ? FREQUENCY : TimeUnit2.DAYS.toMillis(30);
 86    }
 87
 88    /**
 89     * Time till initial ping
 90     */
 91    private static final long TIME_TILL_PING = Long.getLong(ConnectionActivityMonitor.class.getName()+".timeToPing",TimeUnit2.MINUTES.toMillis(3));
 92
 93    private static final long FREQUENCY = Long.getLong(ConnectionActivityMonitor.class.getName()+".frequency",TimeUnit2.SECONDS.toMillis(10));
 94
 95    /**
 96     * When do we abandon the effort and cut off?
 97     */
 98    private static final long TIMEOUT = Long.getLong(ConnectionActivityMonitor.class.getName()+".timeToPing",TimeUnit2.MINUTES.toMillis(4));
 99
100
101    // disabled by default until proven in the production
102    public boolean enabled = Boolean.getBoolean(ConnectionActivityMonitor.class.getName()+".enabled");
103
104    private static final PingCommand PING_COMMAND = new PingCommand();
105    private static final class PingCommand implements Callable<Void,RuntimeException> {
106        public Void call() throws RuntimeException {
107            return null;
108        }
109
110        private static final long serialVersionUID = 1L;
111    }
112
113    private static final Logger LOGGER = Logger.getLogger(ConnectionActivityMonitor.class.getName());
114}