2929import org .apache .log4j .LogMF ;
3030import org .apache .log4j .Logger ;
3131
32+ import java .util .ArrayDeque ;
3233import java .util .Date ;
33- import java .util .LinkedList ;
3434import java .util .Queue ;
3535
3636/**
4646public class Host implements HostStats {
4747 private static final Logger l4j = Logger .getLogger (Host .class );
4848
49- protected static final int DEFAULT_RESPONSE_WINDOW_SIZE = 20 ;
50- protected static final int DEFAULT_ERROR_COOL_DOWN_SECS = 30 ;
49+ public static final int DEFAULT_RESPONSE_WINDOW_SIZE = 25 ;
50+ public static final int DEFAULT_ERROR_COOL_DOWN_SECS = 10 ;
5151
5252 private String name ;
53- protected int responseWindowSize ;
54- protected int errorCoolDownSecs ;
53+ private boolean healthy = true ;
54+ protected int responseWindowSize = DEFAULT_RESPONSE_WINDOW_SIZE ;
55+ protected int errorCoolDownSecs = DEFAULT_ERROR_COOL_DOWN_SECS ;
5556
5657 protected int openConnections ;
5758 protected long lastConnectionTime ;
@@ -60,24 +61,13 @@ public class Host implements HostStats {
6061 protected long consecutiveErrors ;
6162 protected long responseQueueAverage ;
6263
63- protected Queue <Long > responseQueue = new LinkedList <Long >();
64+ protected Queue <Long > responseQueue = new ArrayDeque <Long >();
6465
6566 /**
66- * Uses a default error cool down of 30 secs and a response window size of 20.
67+ * @param name the host name or IP address of this host
6768 */
6869 public Host (String name ) {
69- this (name , DEFAULT_RESPONSE_WINDOW_SIZE , DEFAULT_ERROR_COOL_DOWN_SECS );
70- }
71-
72- /**
73- * @param name the host name or IP address of this host
74- * @param errorCoolDownSecs the cool down period for errors (number of seconds after an error when the host is
75- * considered normalized). compounded for multiple consecutive errors
76- */
77- public Host (String name , int responseWindowSize , int errorCoolDownSecs ) {
7870 this .name = name ;
79- this .responseWindowSize = responseWindowSize ;
80- this .errorCoolDownSecs = errorCoolDownSecs ;
8171 }
8272
8373 public synchronized void connectionOpened () {
@@ -102,7 +92,7 @@ public synchronized void callComplete(long duration, boolean isError) {
10292
10393 // log response time
10494 responseQueue .add (duration );
105- if (responseQueue .size () > responseWindowSize )
95+ while (responseQueue .size () > responseWindowSize )
10696 responseQueue .remove ();
10797
10898 // recalculate average
@@ -120,17 +110,39 @@ public String getName() {
120110 return name ;
121111 }
122112
123- public synchronized long getResponseIndex () {
124- // error adjustment adjust the index up based on the number of consecutive errors
125- long errorAdjustment = consecutiveErrors * errorCoolDownSecs * 1000 ;
113+ public boolean isHealthy () {
114+ return healthy ;
115+ }
116+
117+ public void setHealthy (boolean healthy ) {
118+ this .healthy = healthy ;
119+ }
120+
121+ public long getResponseIndex () {
122+ long currentTime = System .currentTimeMillis ();
126123
127- // open connection adjustment adjusts the index up based on the number of open connections to the host
128- long openConnectionAdjustment = openConnections * errorCoolDownSecs ; // cool down secs as ms instead
124+ synchronized (this ) {
125+ // error adjustment adjust the index up based on the number of consecutive errors
126+ long errorAdjustment = consecutiveErrors * errorCoolDownSecs * 1000 ;
129127
130- // dormant adjustment adjusts the index down based on how long it's been since the host was last used
131- long msSinceLastUse = System . currentTimeMillis () - lastConnectionTime ;
128+ // open connection adjustment adjusts the index up based on the number of open connections to the host
129+ long openConnectionAdjustment = openConnections * errorCoolDownSecs ; // cool down secs as ms instead
132130
133- return responseQueueAverage + errorAdjustment + openConnectionAdjustment - msSinceLastUse ;
131+ // dormant adjustment adjusts the index down based on how long it's been since the host was last used
132+ long msSinceLastUse = currentTime - lastConnectionTime ;
133+
134+ return responseQueueAverage + errorAdjustment + openConnectionAdjustment - msSinceLastUse ;
135+ }
136+ }
137+
138+ /**
139+ * Resets historical metrics. Use with care!
140+ */
141+ public synchronized void resetStats () {
142+ totalConnections = openConnections ;
143+ totalErrors = 0 ;
144+ consecutiveErrors = 0 ;
145+ responseQueueAverage = 0 ;
134146 }
135147
136148 @ Override
@@ -158,9 +170,54 @@ public long getResponseQueueAverage() {
158170 return responseQueueAverage ;
159171 }
160172
173+ public long getConsecutiveErrors () {
174+ return consecutiveErrors ;
175+ }
176+
177+ @ Override
178+ public boolean equals (Object o ) {
179+ if (this == o ) return true ;
180+ if (!(o instanceof Host )) return false ;
181+
182+ Host host = (Host ) o ;
183+
184+ return getName ().equals (host .getName ());
185+ }
186+
187+ @ Override
188+ public int hashCode () {
189+ return getName ().hashCode ();
190+ }
191+
161192 @ Override
162193 public String toString () {
163194 return String .format ("%s{totalConnections=%d, totalErrors=%d, openConnections=%d, lastConnectionTime=%s, responseQueueAverage=%d}" ,
164195 name , totalConnections , totalErrors , openConnections , new Date (lastConnectionTime ).toString (), responseQueueAverage );
165196 }
197+
198+ public int getResponseWindowSize () {
199+ return responseWindowSize ;
200+ }
201+
202+ public void setResponseWindowSize (int responseWindowSize ) {
203+ this .responseWindowSize = responseWindowSize ;
204+ }
205+
206+ public int getErrorCoolDownSecs () {
207+ return errorCoolDownSecs ;
208+ }
209+
210+ public void setErrorCoolDownSecs (int errorCoolDownSecs ) {
211+ this .errorCoolDownSecs = errorCoolDownSecs ;
212+ }
213+
214+ public Host withResponseWindowSize (int responseWindowSize ) {
215+ setResponseWindowSize (responseWindowSize );
216+ return this ;
217+ }
218+
219+ public Host withErrorCoolDownSecs (int errorCoolDownSecs ) {
220+ setErrorCoolDownSecs (errorCoolDownSecs );
221+ return this ;
222+ }
166223}
0 commit comments