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  }