github.com/m3db/m3@v1.5.0/src/cluster/services/types.go (about) 1 // Copyright (c) 2018 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package services 22 23 import ( 24 "time" 25 26 "github.com/m3db/m3/src/cluster/generated/proto/metadatapb" 27 "github.com/m3db/m3/src/cluster/kv" 28 "github.com/m3db/m3/src/cluster/placement" 29 "github.com/m3db/m3/src/cluster/services/leader/campaign" 30 "github.com/m3db/m3/src/cluster/shard" 31 "github.com/m3db/m3/src/x/instrument" 32 xwatch "github.com/m3db/m3/src/x/watch" 33 ) 34 35 // Services provides access to the service topology. 36 type Services interface { 37 // Advertise advertises the availability of an instance of a service. 38 Advertise(ad Advertisement) error 39 40 // Unadvertise indicates a given instance is no longer available. 41 Unadvertise(service ServiceID, id string) error 42 43 // Query returns the topology for a given service. 44 Query(service ServiceID, opts QueryOptions) (Service, error) 45 46 // Watch returns a watch on metadata and a list of available instances for a given service. 47 Watch(service ServiceID, opts QueryOptions) (Watch, error) 48 49 // Metadata returns the metadata for a given service. 50 Metadata(sid ServiceID) (Metadata, error) 51 52 // SetMetadata sets the metadata for a given service. 53 SetMetadata(sid ServiceID, m Metadata) error 54 55 // DeleteMetadata deletes the metadata for a given service 56 DeleteMetadata(sid ServiceID) error 57 58 // PlacementService returns a client of placement.Service. 59 PlacementService(sid ServiceID, popts placement.Options) (placement.Service, error) 60 61 // HeartbeatService returns a heartbeat store for the given service. 62 HeartbeatService(service ServiceID) (HeartbeatService, error) 63 64 // LeaderService returns an instance of a leader service for the given 65 // service ID. 66 LeaderService(service ServiceID, opts ElectionOptions) (LeaderService, error) 67 } 68 69 // KVGen generates a kv store for a given zone. 70 type KVGen func(zone string) (kv.Store, error) 71 72 // HeartbeatGen generates a heartbeat store for a given zone. 73 type HeartbeatGen func(sid ServiceID) (HeartbeatService, error) 74 75 // LeaderGen generates a leader service instance for a given service. 76 type LeaderGen func(sid ServiceID, opts ElectionOptions) (LeaderService, error) 77 78 // Options are options for the client of Services. 79 type Options interface { 80 // InitTimeout is the max time to wait on a new service watch for a valid initial value. 81 // If the value is set to 0, then no wait will be done and the watch could return empty value. 82 InitTimeout() time.Duration 83 84 // SetInitTimeout sets the InitTimeout. 85 SetInitTimeout(t time.Duration) Options 86 87 // KVGen is the function to generate a kv store for a given zone. 88 KVGen() KVGen 89 90 // SetKVGen sets the KVGen. 91 SetKVGen(gen KVGen) Options 92 93 // HeartbeatGen is the function to generate a heartbeat store for a given zone. 94 HeartbeatGen() HeartbeatGen 95 96 // SetHeartbeatGen sets the HeartbeatGen. 97 SetHeartbeatGen(gen HeartbeatGen) Options 98 99 // LeaderGen is the function to generate a leader service instance for a 100 // given service. 101 LeaderGen() LeaderGen 102 103 // SetLeaderGen sets the leader generation function. 104 SetLeaderGen(gen LeaderGen) Options 105 106 // InstrumentsOptions is the instrument options. 107 InstrumentsOptions() instrument.Options 108 109 // SetInstrumentsOptions sets the InstrumentsOptions. 110 SetInstrumentsOptions(iopts instrument.Options) Options 111 112 // NamespaceOptions is the custom namespaces. 113 NamespaceOptions() NamespaceOptions 114 115 // SetNamespaceOptions sets the NamespaceOptions. 116 SetNamespaceOptions(opts NamespaceOptions) Options 117 118 // Validate validates the Options. 119 Validate() error 120 } 121 122 // NamespaceOptions are options to provide custom namespaces in service discovery service. 123 // TODO(cw): Provide overrides for leader service and heartbeat service. 124 type NamespaceOptions interface { 125 // PlacementNamespace is the custom namespace for placement. 126 PlacementNamespace() string 127 128 // SetPlacementNamespace sets the custom namespace for placement. 129 SetPlacementNamespace(v string) NamespaceOptions 130 131 // MetadataNamespace is the custom namespace for metadata. 132 MetadataNamespace() string 133 134 // SetMetadataNamespace sets the custom namespace for metadata. 135 SetMetadataNamespace(v string) NamespaceOptions 136 } 137 138 // OverrideOptions configs the override for service discovery. 139 type OverrideOptions interface { 140 // NamespaceOptions is the namespace options. 141 NamespaceOptions() NamespaceOptions 142 143 // SetNamespaceOptions sets namespace options. 144 SetNamespaceOptions(opts NamespaceOptions) OverrideOptions 145 } 146 147 // Watch is a watcher that issues notification when a service is updated. 148 type Watch interface { 149 // Close closes the watch. 150 Close() 151 152 // C returns the notification channel. 153 C() <-chan struct{} 154 155 // Get returns the latest service of the service watchable. 156 Get() Service 157 } 158 159 // Service describes the metadata and instances of a service. 160 type Service interface { 161 // Instance returns the service instance with the instance id. 162 Instance(instanceID string) (ServiceInstance, error) 163 164 // Instances returns the service instances. 165 Instances() []ServiceInstance 166 167 // SetInstances sets the service instances. 168 SetInstances(insts []ServiceInstance) Service 169 170 // Replication returns the service replication description or nil if none. 171 Replication() ServiceReplication 172 173 // SetReplication sets the service replication description or nil if none. 174 SetReplication(r ServiceReplication) Service 175 176 // Sharding returns the service sharding description or nil if none. 177 Sharding() ServiceSharding 178 179 // SetSharding sets the service sharding description or nil if none 180 SetSharding(s ServiceSharding) Service 181 } 182 183 // ServiceReplication describes the replication of a service. 184 type ServiceReplication interface { 185 // Replicas is the count of replicas. 186 Replicas() int 187 188 // SetReplicas sets the count of replicas. 189 SetReplicas(r int) ServiceReplication 190 } 191 192 // ServiceSharding describes the sharding of a service. 193 type ServiceSharding interface { 194 // NumShards is the number of shards to use for sharding. 195 NumShards() int 196 197 // SetNumShards sets the number of shards to use for sharding. 198 SetNumShards(n int) ServiceSharding 199 200 // IsSharded() returns whether this service is sharded. 201 IsSharded() bool 202 203 // SetIsSharded sets IsSharded. 204 SetIsSharded(s bool) ServiceSharding 205 } 206 207 // ServiceInstance is a single instance of a service. 208 type ServiceInstance interface { 209 // ServiceID returns the service id of the instance. 210 ServiceID() ServiceID 211 212 // SetServiceID sets the service id of the instance. 213 SetServiceID(service ServiceID) ServiceInstance 214 215 // InstanceID returns the id of the instance. 216 InstanceID() string 217 218 // SetInstanceID sets the id of the instance. 219 SetInstanceID(id string) ServiceInstance 220 221 // Endpoint returns the endpoint of the instance. 222 Endpoint() string 223 224 // SetEndpoint sets the endpoint of the instance. 225 SetEndpoint(e string) ServiceInstance 226 227 // Shards returns the shards of the instance. 228 Shards() shard.Shards 229 230 // SetShards sets the shards of the instance. 231 SetShards(s shard.Shards) ServiceInstance 232 } 233 234 // Advertisement advertises the availability of a given instance of a service. 235 type Advertisement interface { 236 // the service being advertised. 237 ServiceID() ServiceID 238 239 // sets the service being advertised. 240 SetServiceID(service ServiceID) Advertisement 241 242 // optional health function, return an error to indicate unhealthy. 243 Health() func() error 244 245 // sets the health function for the advertised instance. 246 SetHealth(health func() error) Advertisement 247 248 // PlacementInstance returns the placement instance associated with this advertisement, which 249 // contains the ID of the instance advertising and all other relevant fields. 250 PlacementInstance() placement.Instance 251 252 // SetPlacementInstance sets the Instance that is advertising. 253 SetPlacementInstance(p placement.Instance) Advertisement 254 } 255 256 // ServiceID contains the fields required to id a service. 257 type ServiceID interface { 258 // Name returns the service name of the ServiceID. 259 Name() string 260 261 // SetName sets the service name of the ServiceID. 262 SetName(s string) ServiceID 263 264 // Environment returns the environment of the ServiceID. 265 Environment() string 266 267 // SetEnvironment sets the environment of the ServiceID. 268 SetEnvironment(env string) ServiceID 269 270 // Zone returns the zone of the ServiceID. 271 Zone() string 272 273 // SetZone sets the zone of the ServiceID. 274 SetZone(zone string) ServiceID 275 276 // Equal retruns if the service IDs are equivalent. 277 Equal(value ServiceID) bool 278 279 // String returns a description of the ServiceID. 280 String() string 281 } 282 283 // QueryOptions are options to service discovery queries. 284 type QueryOptions interface { 285 // IncludeUnhealthy decides whether unhealthy instances should be returned. 286 IncludeUnhealthy() bool 287 288 // SetIncludeUnhealthy sets the value of IncludeUnhealthy. 289 SetIncludeUnhealthy(h bool) QueryOptions 290 291 // InterruptedCh returns the interrupted channel. 292 InterruptedCh() <-chan struct{} 293 294 // SetInterruptedCh sets the interrupted channel. 295 SetInterruptedCh(value <-chan struct{}) QueryOptions 296 } 297 298 // Metadata contains the metadata for a service. 299 type Metadata interface { 300 // String returns a description of the metadata. 301 String() string 302 303 // Port returns the port to be used to contact the service. 304 Port() uint32 305 306 // SetPort sets the port. 307 SetPort(p uint32) Metadata 308 309 // LivenessInterval is the ttl interval for an instance to be considered as healthy. 310 LivenessInterval() time.Duration 311 312 // SetLivenessInterval sets the LivenessInterval. 313 SetLivenessInterval(l time.Duration) Metadata 314 315 // HeartbeatInterval is the interval for heatbeats. 316 HeartbeatInterval() time.Duration 317 318 // SetHeartbeatInterval sets the HeartbeatInterval. 319 SetHeartbeatInterval(h time.Duration) Metadata 320 321 // Proto returns the proto representation for the Metadata. 322 Proto() (*metadatapb.Metadata, error) 323 } 324 325 // HeartbeatService manages heartbeating instances. 326 type HeartbeatService interface { 327 // Heartbeat sends heartbeat for a service instance with a ttl. 328 Heartbeat(instance placement.Instance, ttl time.Duration) error 329 330 // Get gets healthy instances for a service. 331 Get() ([]string, error) 332 333 // GetInstances returns a deserialized list of healthy Instances. 334 GetInstances() ([]placement.Instance, error) 335 336 // Delete deletes the heartbeat for a service instance. 337 Delete(instance string) error 338 339 // Watch watches the heartbeats for a service. 340 Watch() (xwatch.Watch, error) 341 } 342 343 // ElectionOptions configure specific election-scoped options. 344 type ElectionOptions interface { 345 // Duration after which a call to Leader() will timeout if no response 346 // returned from etcd. Defaults to 30 seconds. 347 LeaderTimeout() time.Duration 348 SetLeaderTimeout(t time.Duration) ElectionOptions 349 350 // Duration after which a call to Resign() will timeout if no response 351 // returned from etcd. Defaults to 30 seconds. 352 ResignTimeout() time.Duration 353 SetResignTimeout(t time.Duration) ElectionOptions 354 355 // TTL returns the TTL used for campaigns. By default (ttl == 0), etcd will 356 // set the TTL to 60s. 357 TTLSecs() int 358 SetTTLSecs(ttl int) ElectionOptions 359 } 360 361 // CampaignOptions provide the ability to override campaign defaults. 362 type CampaignOptions interface { 363 // LeaderValue allows the user to override the value a campaign announces 364 // (that is, the value an observer sees upon calling Leader()). This 365 // defaults to the hostname of the caller. 366 LeaderValue() string 367 SetLeaderValue(v string) CampaignOptions 368 } 369 370 // LeaderService provides access to etcd-backed leader elections. 371 type LeaderService interface { 372 // Close closes the election service client entirely. No more campaigns can be 373 // started and any outstanding campaigns are closed. 374 Close() error 375 376 // Campaign proposes that the caller become the leader for a specified 377 // election, with its leadership being refreshed on an interval according to 378 // the ElectionOptions the service was created with. It returns a read-only 379 // channel of campaign status events that is closed when the user resigns 380 // leadership or the campaign is invalidated due to background session 381 // expiration (i.e. failing to refresh etcd leadership lease). The caller 382 // MUST consume this channel until it is closed or risk goroutine leaks. 383 // Users are encouraged to read the package docs of services/leader for 384 // advice on proper usage and common gotchas. 385 // 386 // The leader will announce its hostname to observers unless opts is non-nil 387 // and opts.LeaderValue() is non-empty. 388 Campaign(electionID string, opts CampaignOptions) (<-chan campaign.Status, error) 389 390 // Resign gives up leadership of a specified election if the caller is the 391 // current leader (if the caller is not the leader an error is returned). 392 Resign(electionID string) error 393 394 // Leader returns the current leader of a specified election (if there is no 395 // leader then leader.ErrNoLeader is returned). 396 Leader(electionID string) (string, error) 397 398 // Observe returns a channel on which leader updates for a specified election 399 // will be returned. If no one is campaigning for the given election the call 400 // will still succeed and the channel will receive its first update when an 401 // election is started. 402 Observe(electionID string) (<-chan string, error) 403 }