annotate src/ch/ethz/ssh2/util/TimeoutService.java @ 417:4dcc071e1feb

monitor failure should not kill the TE
author Carl Byington <carl@five-ten-sg.com>
date Wed, 29 Oct 2014 12:12:48 -0700
parents 071eccdff8ea
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
1 /*
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
3 * Please refer to the LICENSE.txt for licensing details.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
4 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
5
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
6 package ch.ethz.ssh2.util;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
7
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
8 import java.io.PrintWriter;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
9 import java.io.StringWriter;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
10 import java.util.Collections;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
11 import java.util.Comparator;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
12 import java.util.LinkedList;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
13
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
14 import ch.ethz.ssh2.log.Logger;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
15
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
16 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
17 * TimeoutService (beta). Here you can register a timeout.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
18 * <p>
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
19 * Implemented having large scale programs in mind: if you open many concurrent SSH connections
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
20 * that rely on timeouts, then there will be only one timeout thread. Once all timeouts
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
21 * have expired/are cancelled, the thread will (sooner or later) exit.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
22 * Only after new timeouts arrive a new thread (singleton) will be instantiated.
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
23 *
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
24 * @author Christian Plattner
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
25 * @version $Id: TimeoutService.java 89 2014-04-07 14:36:24Z dkocher@sudo.ch $
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
26 */
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
27 public class TimeoutService {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
28 private static final Logger log = Logger.getLogger(TimeoutService.class);
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
29
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
30 public static class TimeoutToken {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
31 private long runTime;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
32 private Runnable handler;
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
33
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
34 private TimeoutToken(long runTime, Runnable handler) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
35 this.runTime = runTime;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
36 this.handler = handler;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
37 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
38 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
39
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
40 private static class TimeoutThread extends Thread {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
41 @Override
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
42 public void run() {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
43 synchronized (todolist) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
44 while (true) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
45 if (todolist.size() == 0) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
46 timeoutThread = null;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
47 return;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
48 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
49
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
50 long now = System.currentTimeMillis();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
51 TimeoutToken tt = todolist.getFirst();
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
52
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
53 if (tt.runTime > now) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
54 /* Not ready yet, sleep a little bit */
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
55 try {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
56 todolist.wait(tt.runTime - now);
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
57 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
58 catch (InterruptedException ignored) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
59 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
60
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
61 /* We cannot simply go on, since it could be that the token
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
62 * was removed (cancelled) or another one has been inserted in
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
63 * the meantime.
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
64 */
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
65 continue;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
66 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
67
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
68 todolist.removeFirst();
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
69
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
70 try {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
71 tt.handler.run();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
72 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
73 catch (Exception e) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
74 StringWriter sw = new StringWriter();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
75 e.printStackTrace(new PrintWriter(sw));
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
76 log.warning("Exeception in Timeout handler:" + e.getMessage() + "(" + sw.toString() + ")");
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
77 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
78 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
79 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
80 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
81 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
82
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
83 /* The list object is also used for locking purposes */
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
84 private static final LinkedList<TimeoutToken> todolist = new LinkedList<TimeoutService.TimeoutToken>();
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
85
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
86 private static Thread timeoutThread = null;
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
87
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
88 /**
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
89 * It is assumed that the passed handler will not execute for a long time.
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
90 *
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
91 * @param runTime
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
92 * @param handler
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
93 * @return a TimeoutToken that can be used to cancel the timeout.
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
94 */
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
95 public static TimeoutToken addTimeoutHandler(long runTime, Runnable handler) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
96 TimeoutToken token = new TimeoutToken(runTime, handler);
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
97
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
98 synchronized (todolist) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
99 todolist.add(token);
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
100 Collections.sort(todolist, new Comparator<TimeoutToken>() {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
101 public int compare(TimeoutToken o1, TimeoutToken o2) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
102 if (o1.runTime > o2.runTime)
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
103 return 1;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
104
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
105 if (o1.runTime == o2.runTime)
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
106 return 0;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
107
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
108 return -1;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
109 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
110 });
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
111
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
112 if (timeoutThread != null)
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
113 timeoutThread.interrupt();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
114 else {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
115 timeoutThread = new TimeoutThread();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
116 timeoutThread.setDaemon(true);
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
117 timeoutThread.start();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
118 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
119 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
120
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
121 return token;
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
122 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
123
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
124 public static void cancelTimeoutHandler(TimeoutToken token) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
125 synchronized (todolist) {
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
126 todolist.remove(token);
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
127
307
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
128 if (timeoutThread != null)
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
129 timeoutThread.interrupt();
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
130 }
071eccdff8ea fix java formatting
Carl Byington <carl@five-ten-sg.com>
parents: 273
diff changeset
131 }
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
132
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
133 }