-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconsul_discovery.mbt
More file actions
92 lines (83 loc) · 2.92 KB
/
Copy pathconsul_discovery.mbt
File metadata and controls
92 lines (83 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// The consul-backed discovery driver: the same register -> resolve -> deregister flow
// as the etcd and redis drivers, expressed over consul's agent API. An instance
// registers as a consul service with a TTL check (the lease), a keep-alive passes that
// check, and a client resolves a service to its healthy instances. This is a third
// `Resolve` for the balancer and load-balanced channel, chosen by swapping the driver.
///|
/// A consul-backed service registry / resolver over a `ConsulClient`. Each instance is
/// a consul service named `service`, uniquely identified per agent by its address.
pub struct ConsulDiscovery {
client : ConsulClient
}
///|
/// A consul discovery over `client`.
pub fn ConsulDiscovery::new(client : ConsulClient) -> ConsulDiscovery {
{ client, }
}
///|
/// The per-agent-unique instance id for `endpoint` of `service`:
/// `<service>-<host>-<port>`.
fn consul_instance_id(service : String, endpoint : Endpoint) -> String {
service + "-" + endpoint.host + "-" + endpoint.port.to_string()
}
///|
/// Register `endpoint` for `service` with a `ttl`-second TTL check and immediately pass
/// the check so the instance is healthy at once (a fresh TTL check starts critical).
/// Returns the instance id; renew it with `keepalive` before the TTL lapses.
pub fn ConsulDiscovery::register(
self : ConsulDiscovery,
service : String,
endpoint : Endpoint,
ttl? : Int = 10,
) -> String raise {
let id = consul_instance_id(service, endpoint)
self.client.register_service(id, service, endpoint.host, endpoint.port, ttl)
self.client.check_pass(id)
id
}
///|
/// Refresh an instance's lease by passing its TTL check.
pub fn ConsulDiscovery::keepalive(
self : ConsulDiscovery,
service : String,
endpoint : Endpoint,
) -> Unit raise {
self.client.check_pass(consul_instance_id(service, endpoint))
}
///|
/// Resolve `service` to its healthy endpoints.
pub fn ConsulDiscovery::resolve(
self : ConsulDiscovery,
service : String,
) -> Array[Endpoint] raise {
self.client.health_service(service)
}
///|
/// Deregister one instance of `service`.
pub fn ConsulDiscovery::deregister_instance(
self : ConsulDiscovery,
service : String,
endpoint : Endpoint,
) -> Unit raise {
self.client.deregister_service(consul_instance_id(service, endpoint))
}
///|
/// Deregister every instance of `service` registered on this agent.
pub fn ConsulDiscovery::deregister(
self : ConsulDiscovery,
service : String,
) -> Unit raise {
for pair in self.client.agent_services() {
let (id, name) = pair
if name == service {
self.client.deregister_service(id)
}
}
}
///|
/// This consul discovery as a `Resolve` interface value, so the balancer and the
/// load-balanced channel run against consul unchanged. A resolve error surfaces as an
/// empty endpoint set, matching the other drivers.
pub fn ConsulDiscovery::resolver(self : ConsulDiscovery) -> Resolve {
service => self.resolve(service) catch { _ => [] }
}