18
18
19
19
import java .util .Map ;
20
20
import java .util .concurrent .ConcurrentHashMap ;
21
- import java .util .concurrent .Executors ;
22
- import java .util .concurrent .ScheduledExecutorService ;
23
- import java .util .concurrent .ScheduledFuture ;
24
- import java .util .concurrent .ThreadFactory ;
25
21
import java .util .concurrent .TimeUnit ;
26
22
27
23
import static com .mongodb .ServerConnectionState .Connecting ;
28
- import static java .util .concurrent .TimeUnit .MILLISECONDS ;
29
24
import static org .bson .util .Assertions .isTrue ;
30
25
import static org .bson .util .Assertions .notNull ;
31
26
32
27
class DefaultServer implements ClusterableServer {
33
-
34
- private enum HeartbeatFrequency {
35
- NORMAL {
36
- @ Override
37
- long getFrequencyMS (final ServerSettings settings ) {
38
- return settings .getHeartbeatFrequency (MILLISECONDS );
39
- }
40
- },
41
-
42
- RETRY {
43
- @ Override
44
- long getFrequencyMS (final ServerSettings settings ) {
45
- return settings .getHeartbeatConnectRetryFrequency (MILLISECONDS );
46
- }
47
- };
48
-
49
- abstract long getFrequencyMS (final ServerSettings settings );
50
- }
51
-
52
- private final String clusterId ;
53
- private final ScheduledExecutorService scheduledExecutorService ;
54
28
private final ServerAddress serverAddress ;
55
- private final ServerStateNotifier stateNotifier ;
29
+ private final ServerMonitor serverMonitor ;
56
30
private final PooledConnectionProvider connectionProvider ;
57
31
private final Map <ChangeListener <ServerDescription >, Boolean > changeListeners =
58
32
new ConcurrentHashMap <ChangeListener <ServerDescription >, Boolean >();
59
- private final ServerSettings settings ;
60
33
private final ChangeListener <ServerDescription > serverStateListener ;
61
34
private volatile ServerDescription description ;
62
35
private volatile boolean isClosed ;
63
36
64
- private ScheduledFuture <?> scheduledFuture ;
65
- private HeartbeatFrequency currentFrequency ;
66
-
67
37
public DefaultServer (final ServerAddress serverAddress ,
68
38
final ServerSettings settings ,
69
39
final String clusterId , final PooledConnectionProvider connectionProvider ,
70
40
final Mongo mongo ) {
71
- this .clusterId = notNull ("clusterId" , clusterId );
72
- this .settings = notNull ("settings" , settings );
73
41
this .serverAddress = notNull ("serverAddress" , serverAddress );
74
42
this .description = ServerDescription .builder ().state (Connecting ).address (serverAddress ).build ();
75
43
serverStateListener = new DefaultServerStateListener ();
76
- this .stateNotifier = new ServerStateNotifier (serverAddress , serverStateListener ,
77
- settings .getHeartbeatSocketSettings (), mongo );
78
- this .scheduledExecutorService = Executors .newSingleThreadScheduledExecutor (new DefaultThreadFactory ());
79
- setHeartbeat (0 , HeartbeatFrequency .NORMAL );
44
+ this .serverMonitor = new ServerMonitor (serverAddress , serverStateListener ,
45
+ settings .getHeartbeatSocketSettings (), settings , clusterId , mongo );
46
+ this .serverMonitor .start ();
80
47
this .connectionProvider = connectionProvider ;
81
48
}
82
49
@@ -107,16 +74,13 @@ public void invalidate() {
107
74
serverStateListener .stateChanged (new ChangeEvent <ServerDescription >(description , ServerDescription .builder ()
108
75
.state (Connecting )
109
76
.address (serverAddress ).build ()));
110
- setHeartbeat (0 , HeartbeatFrequency .RETRY );
111
77
connectionProvider .invalidate ();
112
78
}
113
79
114
80
@ Override
115
81
public void close () {
116
82
if (!isClosed ()) {
117
- scheduledFuture .cancel (true );
118
- scheduledExecutorService .shutdownNow ();
119
- stateNotifier .close ();
83
+ serverMonitor .close ();
120
84
connectionProvider .close ();
121
85
isClosed = true ;
122
86
}
@@ -127,34 +91,9 @@ public boolean isClosed() {
127
91
return isClosed ;
128
92
}
129
93
130
- private void setHeartbeat (final ChangeEvent <ServerDescription > event ) {
131
- HeartbeatFrequency heartbeatFrequency = event .getNewValue ().getState () == Connecting
132
- ? HeartbeatFrequency .RETRY
133
- : HeartbeatFrequency .NORMAL ;
134
- long initialDelay = heartbeatFrequency .getFrequencyMS (settings );
135
- setHeartbeat (initialDelay , heartbeatFrequency );
136
- }
137
-
138
- private synchronized void setHeartbeat (final long initialDelay , final HeartbeatFrequency newFrequency ) {
139
- if (currentFrequency != newFrequency ) {
140
- currentFrequency = newFrequency ;
141
- if (scheduledFuture != null ) {
142
- scheduledFuture .cancel (false );
143
- }
144
- scheduledFuture = scheduledExecutorService .scheduleAtFixedRate (stateNotifier , initialDelay ,
145
- newFrequency .getFrequencyMS (settings ),
146
- MILLISECONDS );
147
- }
148
- }
149
-
150
- // Custom thread factory for scheduled executor service that creates daemon threads. Otherwise,
151
- // applications that neglect to close the MongoClient will not exit.
152
- class DefaultThreadFactory implements ThreadFactory {
153
- public Thread newThread (final Runnable runnable ) {
154
- Thread t = new Thread (runnable , "cluster-" + clusterId + "-" + serverAddress );
155
- t .setDaemon (true );
156
- return t ;
157
- }
94
+ @ Override
95
+ public void connect () {
96
+ serverMonitor .connect ();
158
97
}
159
98
160
99
private final class DefaultServerStateListener implements ChangeListener <ServerDescription > {
@@ -164,7 +103,6 @@ public void stateChanged(final ChangeEvent<ServerDescription> event) {
164
103
for (ChangeListener <ServerDescription > listener : changeListeners .keySet ()) {
165
104
listener .stateChanged (event );
166
105
}
167
- setHeartbeat (event );
168
106
}
169
107
}
170
108
}
0 commit comments