...
1
2
3
4
5
6
7 package description
8
9 import (
10 "fmt"
11
12 "go.mongodb.org/mongo-driver/mongo/readpref"
13 )
14
15
16 type Topology struct {
17 Servers []Server
18 SetName string
19 Kind TopologyKind
20
21 SessionTimeoutMinutes uint32
22 SessionTimeoutMinutesPtr *int64
23 CompatibilityErr error
24 }
25
26
27 func (t Topology) String() string {
28 var serversStr string
29 for _, s := range t.Servers {
30 serversStr += "{ " + s.String() + " }, "
31 }
32 return fmt.Sprintf("Type: %s, Servers: [%s]", t.Kind, serversStr)
33 }
34
35
36 func (t Topology) Equal(other Topology) bool {
37 if t.Kind != other.Kind {
38 return false
39 }
40
41 topoServers := make(map[string]Server)
42 for _, s := range t.Servers {
43 topoServers[s.Addr.String()] = s
44 }
45
46 otherServers := make(map[string]Server)
47 for _, s := range other.Servers {
48 otherServers[s.Addr.String()] = s
49 }
50
51 if len(topoServers) != len(otherServers) {
52 return false
53 }
54
55 for _, server := range topoServers {
56 otherServer := otherServers[server.Addr.String()]
57
58 if !server.Equal(otherServer) {
59 return false
60 }
61 }
62
63 return true
64 }
65
66
67
68
69
70
71
72
73 func (t Topology) HasReadableServer(mode readpref.Mode) bool {
74 switch t.Kind {
75 case Single, Sharded:
76 return hasAvailableServer(t.Servers, 0)
77 case ReplicaSetWithPrimary:
78 return hasAvailableServer(t.Servers, mode)
79 case ReplicaSetNoPrimary, ReplicaSet:
80 if mode == readpref.PrimaryMode {
81 return false
82 }
83
84 if !mode.IsValid() {
85 return false
86 }
87
88 return hasAvailableServer(t.Servers, mode)
89 }
90 return false
91 }
92
93
94
95
96
97
98
99 func (t Topology) HasWritableServer() bool {
100 return t.HasReadableServer(readpref.PrimaryMode)
101 }
102
103
104 func hasAvailableServer(servers []Server, mode readpref.Mode) bool {
105 switch mode {
106 case readpref.PrimaryMode:
107 for _, s := range servers {
108 if s.Kind == RSPrimary {
109 return true
110 }
111 }
112 return false
113 case readpref.PrimaryPreferredMode, readpref.SecondaryPreferredMode, readpref.NearestMode:
114 for _, s := range servers {
115 if s.Kind == RSPrimary || s.Kind == RSSecondary {
116 return true
117 }
118 }
119 return false
120 case readpref.SecondaryMode:
121 for _, s := range servers {
122 if s.Kind == RSSecondary {
123 return true
124 }
125 }
126 return false
127 }
128
129
130 for _, s := range servers {
131 switch s.Kind {
132 case Standalone,
133 RSMember,
134 RSPrimary,
135 RSSecondary,
136 RSArbiter,
137 RSGhost,
138 Mongos:
139 return true
140 }
141 }
142
143 return false
144 }
145
View as plain text