forked from mongodb/mongo-java-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMongosStatus.java
More file actions
134 lines (116 loc) · 4.55 KB
/
Copy pathMongosStatus.java
File metadata and controls
134 lines (116 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* Copyright (c) 2008 - 2012 10gen, Inc. <http://10gen.com>
* <p/>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mongodb;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A connection to a set of mongos servers.
*/
class MongosStatus extends ConnectionStatus {
private static final Logger logger = Logger.getLogger("com.mongodb.MongosStatus");
MongosStatus(Mongo mongo, List<ServerAddress> mongosAddresses) {
super(mongosAddresses, mongo);
_updater = new MongosUpdater();
}
@Override
boolean hasServerUp() {
return preferred != null;
}
@Override
Node ensureMaster() {
checkClosed();
return getPreferred();
}
@Override
List<ServerAddress> getServerAddressList() {
return new ArrayList<ServerAddress>(_mongosAddresses);
}
class MongosUpdater extends BackgroundUpdater {
MongosUpdater() {
super("MongosStatus:MongosUpdater");
}
@Override
public void run() {
List<MongosNode> mongosNodes = getMongosNodes();
try {
while (!Thread.interrupted()) {
try {
MongosNode bestThisPass = null;
for (MongosNode cur : mongosNodes) {
cur.update();
if (cur._ok) {
if (bestThisPass == null || (cur._pingTimeMS < bestThisPass._pingTimeMS)) {
bestThisPass = cur;
}
}
}
setPreferred(bestThisPass);
} catch (Exception e) {
logger.log(Level.WARNING, "couldn't do update pass", e);
}
int sleepTime = preferred == null ? updaterIntervalNoMasterMS : updaterIntervalMS;
Thread.sleep(sleepTime);
}
} catch (InterruptedException e) {
logger.log(Level.INFO, "Exiting background thread");
// Allow thread to exit
}
}
private List<MongosNode> getMongosNodes() {
List<MongosNode> mongosNodes = new ArrayList<MongosNode>(_mongosAddresses.size());
for (ServerAddress serverAddress : _mongosAddresses) {
mongosNodes.add(new MongosNode(serverAddress, _mongo, _mongoOptions));
}
return mongosNodes;
}
}
static class MongosNode extends UpdatableNode {
MongosNode(final ServerAddress addr, Mongo mongo, MongoOptions mongoOptions) {
super(addr, mongo, mongoOptions);
}
@Override
protected Logger getLogger() {
return logger;
}
}
// Sends a notification every time preferred is set.
private synchronized void setPreferred(final MongosNode bestThisPass) {
if (bestThisPass == null) {
preferred = null;
} else {
preferred = new Node(bestThisPass._pingTimeMS, bestThisPass._addr, bestThisPass._maxBsonObjectSize, bestThisPass._ok);
}
notifyAll();
}
// Gets the current preferred node. If there is no preferred node, wait to get a notification before returning null.
private synchronized Node getPreferred() {
if (preferred == null) {
try {
synchronized (this) {
wait(_mongo.getMongoOptions().getConnectTimeout());
}
} catch (InterruptedException e) {
throw new MongoInterruptedException("Interrupted while waiting for next update to mongos status", e);
}
}
return preferred;
}
// The current preferred mongos Node to use as the master. This is not necessarily the node that is currently in use.
// Rather, it's the node that is preferred if there is a problem with the currently in use node.
private volatile Node preferred;
}