@@ -48,9 +48,7 @@ class ServerMonitor {
48
48
private final PooledConnectionProvider connectionProvider ;
49
49
private int count ;
50
50
private long elapsedNanosSum ;
51
- private volatile ServerDescription serverDescription ;
52
51
private volatile boolean isClosed ;
53
- private volatile DBPort connection ;
54
52
private final Thread monitorThread ;
55
53
private final Lock lock = new ReentrantLock ();
56
54
private final Condition condition = lock .newCondition ();
@@ -65,7 +63,6 @@ class ServerMonitor {
65
63
this .settings = settings ;
66
64
this .mongo = mongo ;
67
65
this .connectionProvider = connectionProvider ;
68
- serverDescription = getConnectingServerDescription ();
69
66
monitorThread = new Thread (new ServerMonitorRunnable (), "cluster-" + clusterId + "-" + serverAddress );
70
67
monitorThread .setDaemon (true );
71
68
}
@@ -78,16 +75,19 @@ class ServerMonitorRunnable implements Runnable {
78
75
@ Override
79
76
@ SuppressWarnings ("unchecked" )
80
77
public void run () {
78
+ DBPort connection = null ;
81
79
try {
80
+ ServerDescription currentServerDescription = getConnectingServerDescription ();
81
+ Throwable currentException = null ;
82
82
while (!isClosed ) {
83
- ServerDescription currentServerDescription = serverDescription ;
84
- Throwable throwable = null ;
83
+ ServerDescription previousServerDescription = currentServerDescription ;
84
+ Throwable previousException = currentException ;
85
85
try {
86
86
if (connection == null ) {
87
87
connection = new DBPort (serverAddress , null , getOptions (), 0 );
88
88
}
89
89
try {
90
- serverDescription = lookupServerDescription ();
90
+ currentServerDescription = lookupServerDescription (connection );
91
91
} catch (IOException e ) {
92
92
// in case the connection has been reset since the last run, do one retry immediately before reporting that the
93
93
// server is down
@@ -100,22 +100,22 @@ public void run() {
100
100
}
101
101
connection = new DBPort (serverAddress , null , getOptions (), 0 );
102
102
try {
103
- serverDescription = lookupServerDescription ();
103
+ currentServerDescription = lookupServerDescription (connection );
104
104
} catch (IOException e1 ) {
105
105
connection .close ();
106
106
connection = null ;
107
107
throw e1 ;
108
108
}
109
109
}
110
110
} catch (Throwable t ) {
111
- throwable = t ;
112
- serverDescription = getConnectingServerDescription ();
111
+ currentException = t ;
112
+ currentServerDescription = getConnectingServerDescription ();
113
113
}
114
114
115
115
if (!isClosed ) {
116
116
try {
117
- logStateChange (currentServerDescription , throwable );
118
- sendStateChangedEvent (currentServerDescription );
117
+ logStateChange (previousServerDescription , previousException , currentServerDescription , currentException );
118
+ sendStateChangedEvent (previousServerDescription , currentServerDescription );
119
119
} catch (Throwable t ) {
120
120
LOGGER .log (Level .WARNING , "Exception in monitor thread during notification of server state change" , t );
121
121
}
@@ -129,21 +129,25 @@ public void run() {
129
129
}
130
130
}
131
131
132
- private void sendStateChangedEvent (final ServerDescription currentServerDescription ) {
133
- if (!currentServerDescription .equals (serverDescription ) ||
134
- currentServerDescription .getAverageLatencyNanos () != serverDescription .getAverageLatencyNanos ()) {
135
- serverStateListener .stateChanged (new ChangeEvent <ServerDescription >(currentServerDescription , serverDescription ));
132
+ private void sendStateChangedEvent (final ServerDescription previousServerDescription ,
133
+ final ServerDescription currentServerDescription ) {
134
+ if (stateHasChanged (previousServerDescription , currentServerDescription )) {
135
+ serverStateListener .stateChanged (new ChangeEvent <ServerDescription >(previousServerDescription ,
136
+ currentServerDescription ));
136
137
}
137
138
}
138
139
139
- private void logStateChange (final ServerDescription currentServerDescription , final Throwable throwable ) {
140
+ private void logStateChange (final ServerDescription previousServerDescription , final Throwable previousException ,
141
+ final ServerDescription currentServerDescription , final Throwable currentException ) {
140
142
// Note that the ServerDescription.equals method does not include the average ping time as part of the comparison,
141
143
// so this will not spam the logs too hard.
142
- if (!currentServerDescription .equals (serverDescription )) {
143
- if (throwable != null ) {
144
- LOGGER .log (Level .INFO , format ("Exception in monitor thread while connecting to server %s" , serverAddress ), throwable );
144
+ if (descriptionHasChanged (previousServerDescription , currentServerDescription )
145
+ || exceptionHasChanged (previousException , currentException )) {
146
+ if (currentException != null ) {
147
+ LOGGER .log (Level .INFO , format ("Exception in monitor thread while connecting to server %s" , serverAddress ),
148
+ currentException );
145
149
} else {
146
- LOGGER .info (format ("Monitor thread successfully connected to server with description %s" , serverDescription ));
150
+ LOGGER .info (format ("Monitor thread successfully connected to server with description %s" , currentServerDescription ));
147
151
}
148
152
}
149
153
}
@@ -198,7 +202,31 @@ private MongoOptions getOptions() {
198
202
return options ;
199
203
}
200
204
201
- private ServerDescription lookupServerDescription () throws IOException {
205
+ static boolean descriptionHasChanged (final ServerDescription previousServerDescription ,
206
+ final ServerDescription currentServerDescription ) {
207
+ return !previousServerDescription .equals (currentServerDescription );
208
+ }
209
+
210
+ static boolean stateHasChanged (final ServerDescription previousServerDescription , final ServerDescription currentServerDescription ) {
211
+ return descriptionHasChanged (previousServerDescription , currentServerDescription ) ||
212
+ previousServerDescription .getAverageLatencyNanos () != currentServerDescription .getAverageLatencyNanos ();
213
+ }
214
+
215
+ static boolean exceptionHasChanged (final Throwable previousException , final Throwable currentException ) {
216
+ if (currentException == null ) {
217
+ return previousException != null ;
218
+ } else if (previousException == null ) {
219
+ return true ;
220
+ } else if (!currentException .getClass ().equals (previousException .getClass ())) {
221
+ return true ;
222
+ } else if (currentException .getMessage () == null ) {
223
+ return previousException .getMessage () != null ;
224
+ } else {
225
+ return !currentException .getMessage ().equals (previousException .getMessage ());
226
+ }
227
+ }
228
+
229
+ private ServerDescription lookupServerDescription (final DBPort connection ) throws IOException {
202
230
LOGGER .fine (format ("Checking status of %s" , serverAddress ));
203
231
long startNanoTime = System .nanoTime ();
204
232
final CommandResult isMasterResult = connection .runCommand (mongo .getDB ("admin" ), new BasicDBObject ("ismaster" , 1 ));
0 commit comments