github.com/ravendb/ravendb-go-client@v0.0.0-20240229102137-4474ee7aa0fa/tcp_connection_header_message.go (about) 1 package ravendb 2 3 import ( 4 "fmt" 5 "strconv" 6 ) 7 8 type operationTypes = string 9 10 const ( 11 operationNone = "None" 12 operationDrop = "Drop" 13 operationSubscription = "Subscription" 14 operationReplication = "Replication" 15 operationCluster = "Cluster" 16 operationHeartbeats = "Heartbeats" 17 operationPing = "Ping" 18 operationTestConnection = "TestConnection" 19 ) 20 21 const ( 22 numberOfRetriesForSendingTCPHeader = 2 23 pingBaseLine = -1 24 noneBaseLine = -1 25 dropBaseLine = -2 26 hearthbeatsBaseLine = 20 27 subscriptionBaseLine = 40 28 testConnectionBaseLine = 50 29 30 heartbeatsTCPVersion = hearthbeatsBaseLine 31 subscriptionTCPVersion = subscriptionBaseLine 32 testConnectionTCPVersion = testConnectionBaseLine 33 ) 34 35 type tcpConnectionHeaderMessage struct { 36 DatabaseName string `json:"DatabaseName"` 37 SourceNodeTag string `json:"SourceNodeTag"` 38 Operation operationTypes `json:"Operation"` 39 OperationVersion int `json:"OperationVersion"` 40 Info string `json:"Info"` 41 } 42 43 type pingFeatures struct { 44 baseLine bool 45 } 46 47 func newPingFeatures() *pingFeatures { 48 return &pingFeatures{ 49 baseLine: true, 50 } 51 } 52 53 type noneFeatures struct { 54 baseLine bool 55 } 56 57 func newNoneFeatures() *noneFeatures { 58 return &noneFeatures{ 59 baseLine: true, 60 } 61 } 62 63 type dropFeatures struct { 64 baseLine bool 65 } 66 67 func newDropFeatures() *dropFeatures { 68 return &dropFeatures{ 69 baseLine: true, 70 } 71 } 72 73 type subscriptionFeatures struct { 74 baseLine bool 75 } 76 77 func newSubscriptionFeatures() *subscriptionFeatures { 78 return &subscriptionFeatures{ 79 baseLine: true, 80 } 81 } 82 83 type heartbeatsFeatures struct { 84 baseLine bool 85 } 86 87 func newHeartbeatsFeatures() *heartbeatsFeatures { 88 return &heartbeatsFeatures{ 89 baseLine: true, 90 } 91 } 92 93 type testConnectionFeatures struct { 94 baseLine bool 95 } 96 97 func newTestConnectionFeatures() *testConnectionFeatures { 98 return &testConnectionFeatures{ 99 baseLine: true, 100 } 101 } 102 103 type replicationFeatures struct { 104 baseLine bool 105 missingAttachments bool 106 } 107 108 func newReplicationFeatures() *replicationFeatures { 109 return &replicationFeatures{ 110 baseLine: true, 111 } 112 } 113 114 type supportedFeatures struct { 115 protocolVersion int 116 117 ping *pingFeatures 118 none *noneFeatures 119 drop *dropFeatures 120 subscription *subscriptionFeatures 121 heartbeats *heartbeatsFeatures 122 testConnection *testConnectionFeatures 123 } 124 125 func newSupportedFeatures(version int) *supportedFeatures { 126 return &supportedFeatures{ 127 protocolVersion: version, 128 } 129 } 130 131 var ( 132 operationsToSupportedProtocolVersions = map[operationTypes][]int{} 133 supportedFeaturesByProtocol = map[operationTypes]map[int]*supportedFeatures{} 134 ) 135 136 func init() { 137 operationsToSupportedProtocolVersions[operationPing] = []int{pingBaseLine} 138 operationsToSupportedProtocolVersions[operationNone] = []int{noneBaseLine} 139 operationsToSupportedProtocolVersions[operationDrop] = []int{dropBaseLine} 140 operationsToSupportedProtocolVersions[operationSubscription] = []int{subscriptionBaseLine} 141 operationsToSupportedProtocolVersions[operationHeartbeats] = []int{hearthbeatsBaseLine} 142 operationsToSupportedProtocolVersions[operationTestConnection] = []int{testConnectionBaseLine} 143 144 pingFeaturesMap := map[int]*supportedFeatures{} 145 supportedFeaturesByProtocol[operationPing] = pingFeaturesMap 146 pingFeatures := newSupportedFeatures(pingBaseLine) 147 pingFeatures.ping = newPingFeatures() 148 pingFeaturesMap[pingBaseLine] = pingFeatures 149 150 noneFeaturesMap := map[int]*supportedFeatures{} 151 supportedFeaturesByProtocol[operationNone] = noneFeaturesMap 152 noneFeatures := newSupportedFeatures(noneBaseLine) 153 noneFeatures.none = newNoneFeatures() 154 noneFeaturesMap[noneBaseLine] = noneFeatures 155 156 dropFeaturesMap := map[int]*supportedFeatures{} 157 supportedFeaturesByProtocol[operationDrop] = dropFeaturesMap 158 dropFeatures := newSupportedFeatures(dropBaseLine) 159 dropFeatures.drop = newDropFeatures() 160 dropFeaturesMap[dropBaseLine] = dropFeatures 161 162 subscriptionFeaturesMap := map[int]*supportedFeatures{} 163 supportedFeaturesByProtocol[operationSubscription] = subscriptionFeaturesMap 164 subscriptionFeatures := newSupportedFeatures(subscriptionBaseLine) 165 subscriptionFeatures.subscription = newSubscriptionFeatures() 166 subscriptionFeaturesMap[subscriptionBaseLine] = subscriptionFeatures 167 168 heartbeatsFeaturesMap := map[int]*supportedFeatures{} 169 supportedFeaturesByProtocol[operationHeartbeats] = heartbeatsFeaturesMap 170 heartbeatsFeatures := newSupportedFeatures(hearthbeatsBaseLine) 171 heartbeatsFeatures.heartbeats = newHeartbeatsFeatures() 172 heartbeatsFeaturesMap[hearthbeatsBaseLine] = heartbeatsFeatures 173 174 testConnectionFeaturesMap := map[int]*supportedFeatures{} 175 supportedFeaturesByProtocol[operationTestConnection] = testConnectionFeaturesMap 176 testConnectionFeatures := newSupportedFeatures(testConnectionBaseLine) 177 testConnectionFeatures.testConnection = newTestConnectionFeatures() 178 testConnectionFeaturesMap[testConnectionBaseLine] = testConnectionFeatures 179 180 } 181 182 var ( 183 // validate 184 operations = []operationTypes{ 185 operationCluster, 186 operationDrop, 187 operationHeartbeats, 188 operationNone, 189 operationPing, 190 operationReplication, 191 operationSubscription, 192 operationTestConnection, 193 } 194 ) 195 196 type supportedStatus int 197 198 const ( 199 supportedStatus_OUT_OF_RANGE supportedStatus = iota 200 supportedStatus_NOT_SUPPORTED 201 supportedStatus_SUPPORTED 202 ) 203 204 func operationVersionSupported(operationType operationTypes, version int, currentRef *int) supportedStatus { 205 *currentRef = -1 206 207 supportedProtocols := operationsToSupportedProtocolVersions[operationType] 208 panicIf(len(supportedProtocols) == 0, "This is a bug. Probably you forgot to add '"+operationType+"' operation to the operationsToSupportedProtocolVersions map") 209 210 for i := 0; i < len(supportedProtocols); i++ { 211 *currentRef = supportedProtocols[i] 212 if *currentRef == version { 213 return supportedStatus_SUPPORTED 214 } 215 216 if *currentRef < version { 217 return supportedStatus_NOT_SUPPORTED 218 } 219 } 220 221 return supportedStatus_OUT_OF_RANGE 222 } 223 224 func getOperationTcpVersion(operationType operationTypes, index int) int { 225 // we don't check the if the index go out of range, since this is expected and means that we don't have 226 switch operationType { 227 case operationPing, operationNone: 228 return -1 229 case operationDrop: 230 return -2 231 case operationSubscription, operationReplication, operationCluster, 232 operationHeartbeats, operationTestConnection: 233 return operationsToSupportedProtocolVersions[operationType][index] 234 default: 235 panic(fmt.Sprintf("invalid operationType '%v'", operationType)) 236 } 237 } 238 239 func getSupportedFeaturesFor(typ operationTypes, protocolVersion int) *supportedFeatures { 240 features := supportedFeaturesByProtocol[typ][protocolVersion] 241 panicIf(features == nil, typ+" in protocol "+strconv.Itoa(protocolVersion)+" was not found in the features set") 242 return features 243 }