]> go.fuhry.dev Git - runtime.git/commitdiff
[sd] differentiate node name and shard name
authorDan Fuhry <dan@fuhry.com>
Sat, 22 Mar 2025 02:49:08 +0000 (22:49 -0400)
committerDan Fuhry <dan@fuhry.com>
Sat, 22 Mar 2025 02:49:08 +0000 (22:49 -0400)
Shard is not always applicable to sd entries, but sd entries do need
some kind of discriminator for etcd path collision avoidance.

Use the first element of the hostname for collision avoidance, and make
shard an optional element that nests items one level deeper.

sd/healthcheck.go
sd/healthcheck_http.go
sd/healthcheck_ldap.go
sd/publish.go
sd/watcher.go

index fd87d1040cae432e5b6762cefa4b6d23a16fb2c1..89163a3bb8e5e2d9b9c04dc15255a73f2f1295c8 100644 (file)
@@ -54,6 +54,7 @@ type HealthStatus uint
 type ServiceDefinition struct {
        Engine       string `json:"type"`
        ServiceName  string `json:"service_name"`
+       Shard        string `json:"shard"`
        PollInterval uint   `json:"poll_interval"`
 }
 
index 00a54d9cc0fb8d4e63a1d2ff34805a3dd9e6c52b..773af2b6c0c87663b1507916eb0f9faddbbf9ab7 100644 (file)
@@ -63,6 +63,10 @@ func (hcs *httpHealthCheckService) ServiceDefinition() *ServiceDefinition {
 
 func (hcs *httpHealthCheckService) NewPublisher(domain string, regions []string) *SDPublisher {
        _, port := hcs.PublishAddress()
+       shard := hcs.serviceDef.Shard
+       if shard == "" {
+               shard = strings.Split(hcs.SocketHost, ".")[0]
+       }
 
        publisher := &SDPublisher{
                AdvertiseHost: hcs.SocketHost,
@@ -70,7 +74,7 @@ func (hcs *httpHealthCheckService) NewPublisher(domain string, regions []string)
                Domain:        domain,
                Protocol:      ProtocolTCP,
                Service:       hcs.serviceDef.ServiceName,
-               ShardName:     strings.Split(hcs.SocketHost, ".")[0],
+               ShardName:     shard,
                Regions:       regions,
        }
 
index 5b54ae0fc6994c03c7c275ce9748a688ff00e2cc..cc000846b0d99100dab44d32119b773b4c4ee3db 100644 (file)
@@ -58,6 +58,10 @@ func (lcs *ldapHealthCheckService) ServiceDefinition() *ServiceDefinition {
 
 func (lcs *ldapHealthCheckService) NewPublisher(domain string, regions []string) *SDPublisher {
        _, port := lcs.PublishAddress()
+       shard := lcs.serviceDef.Shard
+       if shard == "" {
+               shard = strings.Split(lcs.SocketHost, ".")[0]
+       }
 
        publisher := &SDPublisher{
                AdvertiseHost: lcs.SocketHost,
@@ -65,7 +69,7 @@ func (lcs *ldapHealthCheckService) NewPublisher(domain string, regions []string)
                Domain:        domain,
                Protocol:      ProtocolTCP,
                Service:       lcs.serviceDef.ServiceName,
-               ShardName:     strings.Split(lcs.SocketHost, ".")[0],
+               ShardName:     shard,
                Regions:       regions,
        }
 
index 02f01d1171890a2d0f1d19b62e6b8fe302eb9d5b..abe5c5bdde8ea6f68ea2113bfd27d23c6302d9a1 100644 (file)
@@ -28,6 +28,7 @@ type SDPublisher struct {
        Domain        string
        Protocol      Layer4Protocol
        Service       string
+       NodeName      string
        ShardName     string
        LocalRegion   string
        Regions       []string
@@ -100,8 +101,8 @@ func (s *SDPublisher) init() error {
                errors = append(errors, "service name was not set")
        }
 
-       if s.ShardName == "" {
-               s.ShardName = hostname.Hostname()
+       if s.NodeName == "" {
+               s.NodeName = hostname.Hostname()
        }
 
        if s.LocalRegion == "" {
@@ -291,12 +292,17 @@ func (s *SDPublisher) renewalTick() {
 
 func (s *SDPublisher) srvRecordPath() string {
        domainPathComponents := strings.Join(utils.Reverse(strings.Split(s.Domain, ".")), "/")
-       return fmt.Sprintf("/sd/%s/%s/%s/_%s/%s",
+       shardName := ""
+       if s.ShardName != "" {
+               shardName = "/" + s.ShardName
+       }
+       return fmt.Sprintf("/sd/%s/%s/%s/_%s/%s%s",
                "dns",
                domainPathComponents,
                s.Protocol.DNSComponent(),
                s.Service,
-               s.ShardName)
+               s.NodeName,
+               shardName)
 }
 
 func (s *SDPublisher) srvRecordJson(region string) string {
@@ -316,11 +322,16 @@ func (s *SDPublisher) srvRecordJson(region string) string {
 
 func (s *SDPublisher) aRecordPath() string {
        domainPathComponents := strings.Join(utils.Reverse(strings.Split(s.Domain, ".")), "/")
-       return fmt.Sprintf("/sd/%s/%s/%s/%s/a",
+       shardName := ""
+       if s.ShardName != "" {
+               shardName = "/" + s.ShardName
+       }
+       return fmt.Sprintf("/sd/%s/%s/%s/%s%s/a",
                "dns",
                domainPathComponents,
                s.Service,
-               s.ShardName)
+               s.NodeName,
+               shardName)
 }
 
 func (s *SDPublisher) aRecordJson() string {
@@ -334,11 +345,16 @@ func (s *SDPublisher) aRecordJson() string {
 
 func (s *SDPublisher) aaaaRecordPath() string {
        domainPathComponents := strings.Join(utils.Reverse(strings.Split(s.Domain, ".")), "/")
-       return fmt.Sprintf("/sd/%s/%s/%s/%s/aaaa",
+       shardName := ""
+       if s.ShardName != "" {
+               shardName = "/" + s.ShardName
+       }
+       return fmt.Sprintf("/sd/%s/%s/%s/%s%s/aaaa",
                "dns",
                domainPathComponents,
                s.Service,
-               s.ShardName)
+               s.NodeName,
+               shardName)
 }
 
 func (s *SDPublisher) aaaaRecordJson() string {
index 8eca2e9e063faaee7abe6ea4ba1c27d71d47b385..5d95d1771c6f8322c2265a76bad27ac62b805210 100644 (file)
@@ -39,6 +39,7 @@ type ServiceAddress struct {
        IP6      string
        Protocol Layer4Protocol
        Service  string
+       Node     string
        Shard    string
 
        key string
@@ -208,7 +209,13 @@ func (w *SDWatcher) buildResult(kvs map[string][]byte) []ServiceAddress {
                if len(components) == 3 {
                        sa.Protocol, _ = Layer4ProtocolFromString(components[0])
                        sa.Service = components[1][1:]
+                       sa.Node = components[2]
                        sa.Shard = components[2]
+               } else if len(components) == 4 {
+                       sa.Protocol, _ = Layer4ProtocolFromString(components[0])
+                       sa.Service = components[1][1:]
+                       sa.Node = components[2]
+                       sa.Shard = components[3]
                }
                sas = append(sas, sa)
        }