@@ -29,9 +29,13 @@ func newFSM() *fsm {
29
29
return new (fsm )
30
30
}
31
31
32
- // apply should operate on immutable TopologyDescriptions and Descriptions. This way we don't have to
33
- // lock for the entire time we're applying server description.
34
- func (f * fsm ) apply (s description.Server ) (description.Topology , error ) {
32
+ // apply takes a new server description and modifies the FSM's topology description based on it. It returns the
33
+ // updated topology description as well as a server description. The returned server description is either the same
34
+ // one that was passed in, or a new one in the case that it had to be changed.
35
+ //
36
+ // apply should operation on immutable descriptions so we don't have to lock for the entire time we're applying the
37
+ // server description.
38
+ func (f * fsm ) apply (s description.Server ) (description.Topology , description.Server , error ) {
35
39
36
40
newServers := make ([]description.Server , len (f .Servers ))
37
41
copy (newServers , f .Servers )
@@ -62,12 +66,12 @@ func (f *fsm) apply(s description.Server) (description.Topology, error) {
62
66
}
63
67
64
68
if _ , ok := f .findServer (s .Addr ); ! ok {
65
- return f .Topology , nil
69
+ return f .Topology , s , nil
66
70
}
67
71
68
72
if s .WireVersion != nil {
69
73
if s .WireVersion .Max < supportedWireVersions .Min {
70
- return description.Topology {}, fmt .Errorf (
74
+ return description.Topology {}, s , fmt .Errorf (
71
75
"server at %s reports wire version %d, but this version of the Go driver requires " +
72
76
"at least %d (MongoDB %s)" ,
73
77
s .Addr .String (),
@@ -78,7 +82,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, error) {
78
82
}
79
83
80
84
if s .WireVersion .Min > supportedWireVersions .Max {
81
- return description.Topology {}, fmt .Errorf (
85
+ return description.Topology {}, s , fmt .Errorf (
82
86
"server at %s requires wire version %d, but this version of the Go driver only " +
83
87
"supports up to %d" ,
84
88
s .Addr .String (),
@@ -88,23 +92,24 @@ func (f *fsm) apply(s description.Server) (description.Topology, error) {
88
92
}
89
93
}
90
94
95
+ updatedDesc := s
91
96
switch f .Kind {
92
97
case description .Unknown :
93
- f .applyToUnknown (s )
98
+ updatedDesc = f .applyToUnknown (s )
94
99
case description .Sharded :
95
- f .applyToSharded (s )
100
+ updatedDesc = f .applyToSharded (s )
96
101
case description .ReplicaSetNoPrimary :
97
- f .applyToReplicaSetNoPrimary (s )
102
+ updatedDesc = f .applyToReplicaSetNoPrimary (s )
98
103
case description .ReplicaSetWithPrimary :
99
- f .applyToReplicaSetWithPrimary (s )
104
+ updatedDesc = f .applyToReplicaSetWithPrimary (s )
100
105
case description .Single :
101
- f .applyToSingle (s )
106
+ updatedDesc = f .applyToSingle (s )
102
107
}
103
108
104
- return f .Topology , nil
109
+ return f .Topology , updatedDesc , nil
105
110
}
106
111
107
- func (f * fsm ) applyToReplicaSetNoPrimary (s description.Server ) {
112
+ func (f * fsm ) applyToReplicaSetNoPrimary (s description.Server ) description. Server {
108
113
switch s .Kind {
109
114
case description .Standalone , description .Mongos :
110
115
f .removeServerByAddr (s .Addr )
@@ -115,9 +120,11 @@ func (f *fsm) applyToReplicaSetNoPrimary(s description.Server) {
115
120
case description .Unknown , description .RSGhost :
116
121
f .replaceServer (s )
117
122
}
123
+
124
+ return s
118
125
}
119
126
120
- func (f * fsm ) applyToReplicaSetWithPrimary (s description.Server ) {
127
+ func (f * fsm ) applyToReplicaSetWithPrimary (s description.Server ) description. Server {
121
128
switch s .Kind {
122
129
case description .Standalone , description .Mongos :
123
130
f .removeServerByAddr (s .Addr )
@@ -130,39 +137,53 @@ func (f *fsm) applyToReplicaSetWithPrimary(s description.Server) {
130
137
f .replaceServer (s )
131
138
f .checkIfHasPrimary ()
132
139
}
140
+
141
+ return s
133
142
}
134
143
135
- func (f * fsm ) applyToSharded (s description.Server ) {
144
+ func (f * fsm ) applyToSharded (s description.Server ) description. Server {
136
145
switch s .Kind {
137
146
case description .Mongos , description .Unknown :
138
147
f .replaceServer (s )
139
148
case description .Standalone , description .RSPrimary , description .RSSecondary , description .RSArbiter , description .RSMember , description .RSGhost :
140
149
f .removeServerByAddr (s .Addr )
141
150
}
151
+
152
+ return s
142
153
}
143
154
144
- func (f * fsm ) applyToSingle (s description.Server ) {
155
+ func (f * fsm ) applyToSingle (s description.Server ) description. Server {
145
156
switch s .Kind {
146
157
case description .Unknown :
147
158
f .replaceServer (s )
148
159
case description .Standalone , description .Mongos :
149
160
if f .SetName != "" {
150
161
f .removeServerByAddr (s .Addr )
151
- return
162
+ return s
152
163
}
153
164
154
165
f .replaceServer (s )
155
166
case description .RSPrimary , description .RSSecondary , description .RSArbiter , description .RSMember , description .RSGhost :
167
+ // A replica set name can be provided when creating a direct connection. In this case, if the set name returned
168
+ // by the isMaster response doesn't match up with the one provided during configuration, the server description
169
+ // is replaced with a default Unknown description.
170
+ //
171
+ // We create a new server description rather than doing s.Kind = description.Unknown because the other fields,
172
+ // such as RTT, need to be cleared for Unknown descriptions as well.
156
173
if f .SetName != "" && f .SetName != s .SetName {
157
- f .removeServerByAddr (s .Addr )
158
- return
174
+ s = description.Server {
175
+ Addr : s .Addr ,
176
+ Kind : description .Unknown ,
177
+ }
159
178
}
160
179
161
180
f .replaceServer (s )
162
181
}
182
+
183
+ return s
163
184
}
164
185
165
- func (f * fsm ) applyToUnknown (s description.Server ) {
186
+ func (f * fsm ) applyToUnknown (s description.Server ) description. Server {
166
187
switch s .Kind {
167
188
case description .Mongos :
168
189
f .setKind (description .Sharded )
@@ -177,6 +198,8 @@ func (f *fsm) applyToUnknown(s description.Server) {
177
198
case description .Unknown , description .RSGhost :
178
199
f .replaceServer (s )
179
200
}
201
+
202
+ return s
180
203
}
181
204
182
205
func (f * fsm ) checkIfHasPrimary () {
0 commit comments