mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
feat(caddy): order local machine upstreams first in generated Caddyfile
This commit is contained in:
@@ -112,17 +112,23 @@ func NewCaddyfileGenerator(
|
|||||||
func (g *CaddyfileGenerator) Generate(
|
func (g *CaddyfileGenerator) Generate(
|
||||||
ctx context.Context, records []store.ContainerRecord, includeCustom bool,
|
ctx context.Context, records []store.ContainerRecord, includeCustom bool,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
|
// Sort records by local machine first, then by service name and creation time. Placing containers on the local
|
||||||
|
// machine first lets user-defined Caddy configs pair this ordering with the "first" lb_policy to always send
|
||||||
|
// traffic to the same-host replica (skipping the cross-machine hop) and only fall back to remote upstreams when
|
||||||
|
// the local one is unhealthy.
|
||||||
|
// The service name and creation time tiebreakers keep the generated Caddyfile stable across regenerations.
|
||||||
|
slices.SortStableFunc(records, func(a, b store.ContainerRecord) int {
|
||||||
|
return cmp.Or(
|
||||||
|
g.localMachineRank(a.MachineID)-g.localMachineRank(b.MachineID),
|
||||||
|
strings.Compare(a.Container.ServiceName(), b.Container.ServiceName()),
|
||||||
|
a.Container.CreatedTime().Compare(b.Container.CreatedTime()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
containers := make([]api.ServiceContainer, len(records))
|
containers := make([]api.ServiceContainer, len(records))
|
||||||
for i, cr := range records {
|
for i, cr := range records {
|
||||||
containers[i] = cr.Container
|
containers[i] = cr.Container
|
||||||
}
|
}
|
||||||
// Sort containers by service name and creation time to generate a stable Caddyfile.
|
|
||||||
slices.SortStableFunc(containers, func(a, b api.ServiceContainer) int {
|
|
||||||
return cmp.Or(
|
|
||||||
strings.Compare(a.ServiceName(), b.ServiceName()),
|
|
||||||
a.CreatedTime().Compare(b.CreatedTime()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
caddyfile, err := g.generateBaseFromPorts(containers)
|
caddyfile, err := g.generateBaseFromPorts(containers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -243,6 +249,15 @@ func (g *CaddyfileGenerator) Generate(
|
|||||||
return caddyfileHeader + "\n" + caddyfile, nil
|
return caddyfileHeader + "\n" + caddyfile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// localMachineRank returns 0 if the given machineID matches the local machine and 1 otherwise.
|
||||||
|
// Useful for sorting containers running locally first.
|
||||||
|
func (g *CaddyfileGenerator) localMachineRank(machineID string) int {
|
||||||
|
if g.machineID == machineID {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
func (g *CaddyfileGenerator) generateBaseFromPorts(containers []api.ServiceContainer) (string, error) {
|
func (g *CaddyfileGenerator) generateBaseFromPorts(containers []api.ServiceContainer) (string, error) {
|
||||||
httpHostUpstreams, httpsHostUpstreams := httpUpstreamsFromPorts(containers)
|
httpHostUpstreams, httpsHostUpstreams := httpUpstreamsFromPorts(containers)
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,25 @@ https://secure.example.com {
|
|||||||
}
|
}
|
||||||
log
|
log
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "local machine upstreams listed first",
|
||||||
|
containers: []store.ContainerRecord{
|
||||||
|
newContainerRecord(newContainer("10.210.0.2", "app.example.com:8080/http"), "mach1"),
|
||||||
|
newContainerRecord(newContainer("10.210.1.2", "app.example.com:8080/http"), "test-machine-id"),
|
||||||
|
newContainerRecord(newContainer("10.210.2.2", "app.example.com:8080/http"), "mach2"),
|
||||||
|
newContainerRecord(newContainer("10.210.1.3", "app.example.com:8080/http"), "test-machine-id"),
|
||||||
|
},
|
||||||
|
want: testCaddyfileHeader + `
|
||||||
|
# Sites generated from service ports.
|
||||||
|
|
||||||
|
http://app.example.com {
|
||||||
|
reverse_proxy 10.210.1.2:8080 10.210.1.3:8080 10.210.0.2:8080 10.210.2.2:8080 {
|
||||||
|
import common_proxy
|
||||||
|
}
|
||||||
|
log
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user