linkerd2/proto/proxy/destination/destination.proto

90 lines
3.5 KiB
Protocol Buffer

syntax = "proto3";
package conduit.proxy.destination;
import "common/common.proto";
/// Destination Service ///
//
// This is the service discovery API. Given a destination, this returns a
// weighted set of addresses and address metadata. Can be implemented with DNS
// or lookups against other service discovery backends.
//
// If the service does not exist then the controller must send
// `no_endpoints{exists: false}` ASAP when a client subscribes or when the
// service stops existing. If the service exists and has endpoints available
// then the controller must send `add` that lists all (or at least a large
// number) of the endpoints for the service. If and only if the service exists
// but does not have any endpoints available then the controller SHOULD send
// `no_endpoints{exists: true}` when a client subscribes. In other words, the
// `no_endpoints` message must only be sent when there are *no*endpoints for
// the service.
//
// The controller is expected to send an Update every time there is a
// change in service discovery. The controller is also expected to send an
// update at least once every ADDRESS_UPDATE_INTERVAL to indicate that the
// controller is still healthy. If no service discovery updates have taken
// place, the controller can simply send an empty `add`. The controller may
// determine the value of ADDRESS_UPDATE_INTERVAL.
//
// The client MUST be prepared to receive messages in any order and the client
// MUST be able to cope with the presence or absence of redundant messages.
//
// `no_endpoints` followed by an `add` is *not* equivalent to just sending the
// `add` regardless of the value of the `exists` field in the `no_endpoints`
// message. `remove` followed by a `no_endpoints` message is equivalent to
// sending just the `no_endpoints` message, and a `remove` that removes the
// last endpoint is equivalent to a `no_endpoints{exists: true}` message.
//
// When the client gets disconnected from the controller and reconnects, the
// client may use stale results from its previous subscription until, and only
// until, it receives the first message. This is why the controller must send
// a message at the start of a subscription. This is also why the controller
// must not send a `no_endpoints` message before an `add` message; the client
// would clear its cached messages between the time it receives the
// `no_endpoints` message and the time it receives the `add` message, which is
// not the desired behavior.
service Destination {
// Given a destination, return all addresses in that destination as a long-
// running stream of updates.
rpc Get(common.Destination) returns (stream Update) {}
}
message Update {
oneof update {
// A new set of endpoints are available for the service. The set might be
// empty.
WeightedAddrSet add = 1;
// Some endpoints have been removed from the service.
AddrSet remove = 2;
// `no_endpoints{exists: false}` indicates that the service does not exist
// and the client MAY try an alternate service discovery method (e.g. DNS).
//
// `no_endpoints(exists: true)` indicates that the service does exist and
// the client MUST NOT fall back to an alternate service discovery method.
NoEndpoints no_endpoints = 3;
}
}
message AddrSet {
repeated common.TcpAddress addrs = 1;
}
message WeightedAddrSet {
repeated WeightedAddr addrs = 1;
map<string, string> metric_labels = 2;
}
message WeightedAddr {
common.TcpAddress addr = 1;
uint32 weight = 3;
map<string, string> metric_labels = 4;
}
message NoEndpoints {
bool exists = 1;
}