Skip to content

Commit 65cdb23

Browse files
compute-domain-daemon: avoid SIGUSR1 on peer removals only
Signed-off-by: AkshatDudeja77 <akshat.dudeja77@gmail.com>
1 parent 4fc3ff0 commit 65cdb23

3 files changed

Lines changed: 111 additions & 10 deletions

File tree

cmd/compute-domain-daemon/main.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,24 @@ func IMEXDaemonUpdateLoopWithIPs(ctx context.Context, controller *Controller, cl
359359
}
360360
}
361361

362+
// shouldSendSIGUSR1 determines whether the IMEX daemon should be
363+
// signaled to re-resolve and reconnect to peers.
364+
//
365+
// fresh indicates whether the IMEX daemon process was just started.
366+
//
367+
// The signal is sent only when:
368+
// - the mapping was updated,
369+
// - the process is not fresh, and
370+
// - at least one new IP (peer) was added.
371+
func shouldSendSIGUSR1(oldIPs, newIPs IPSet, fresh bool) bool {
372+
if fresh {
373+
return false
374+
}
375+
376+
added, _ := oldIPs.Diff(newIPs)
377+
return len(added) > 0
378+
}
379+
362380
// IMEXDaemonUpdateLoopWithDNSNames reacts to ComputeDomain status changes by
363381
// updating the /etc/hosts file with IP to DNS name mappings. This relies on
364382
// the IMEX daemon to pick up these changes automatically (and quickly) --
@@ -374,6 +392,10 @@ func IMEXDaemonUpdateLoopWithDNSNames(ctx context.Context, controller *Controlle
374392
klog.Infof("shutdown: stop IMEXDaemonUpdateLoopWithDNSNames")
375393
return nil
376394
case daemons := <-controller.GetDaemonInfoUpdateChan():
395+
oldIPs := make(map[string]struct{}, len(dnsNameManager.ipToDNSName))
396+
for ip := range dnsNameManager.ipToDNSName {
397+
oldIPs[ip] = struct{}{}
398+
}
377399
updated, err := dnsNameManager.UpdateDNSNameMappings(daemons)
378400
if err != nil {
379401
return fmt.Errorf("failed to update DNS name => IP mappings: %w", err)
@@ -390,13 +412,16 @@ func IMEXDaemonUpdateLoopWithDNSNames(ctx context.Context, controller *Controlle
390412
}
391413

392414
dnsNameManager.LogDNSNameMappings()
415+
// Skip sending SIGUSR1 when:
416+
// - the process is fresh (has newly been started), or
417+
// - this was a noop update, or
418+
// - no new peers were added (i.e. the update only removes nodes or keeps the set unchanged).
419+
newIPs := make(IPSet, len(dnsNameManager.ipToDNSName))
420+
for ip := range dnsNameManager.ipToDNSName {
421+
newIPs[ip] = struct{}{}
422+
}
393423

394-
// Skip sending SIGUSR1 when the process is fresh (has newly been
395-
// created) or when this was a noop update. TODO: review skipping
396-
// this also if the new set of IP addresses only strictly removes
397-
// addresses compared to the old set (then we don't need to force
398-
// the daemon to re-resolve & re-connect).
399-
if !updated || fresh {
424+
if !updated || !shouldSendSIGUSR1(IPSet(oldIPs), newIPs, fresh) {
400425
break
401426
}
402427

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package main
2+
3+
import "testing"
4+
5+
func set(items ...string) IPSet {
6+
m := make(IPSet, len(items))
7+
for _, i := range items {
8+
m[i] = struct{}{}
9+
}
10+
return m
11+
}
12+
13+
func TestShouldSendSIGUSR1(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
old IPSet
17+
new IPSet
18+
fresh bool
19+
want bool
20+
}{
21+
{
22+
name: "no change",
23+
old: set("A", "B", "C"),
24+
new: set("A", "B", "C"),
25+
fresh: false,
26+
want: false,
27+
},
28+
{
29+
name: "no change",
30+
old: set("A", "B", "C"),
31+
new: set("A", "B", "C"),
32+
fresh: false,
33+
want: false,
34+
},
35+
{
36+
name: "pure removal",
37+
old: set("A", "B", "C"),
38+
new: set("A", "B"),
39+
fresh: false,
40+
want: false,
41+
},
42+
{
43+
name: "addition",
44+
old: set("A", "B"),
45+
new: set("A", "B", "C"),
46+
fresh: false,
47+
want: true,
48+
},
49+
{
50+
name: "replacement same size",
51+
old: set("A", "B", "C"),
52+
new: set("A", "B", "D"),
53+
fresh: false,
54+
want: true,
55+
},
56+
{
57+
name: "remove and add",
58+
old: set("A", "B", "C"),
59+
new: set("A", "D"),
60+
fresh: false,
61+
want: true,
62+
},
63+
{
64+
name: "fresh process",
65+
old: set("A", "B"),
66+
new: set("A", "B", "C"),
67+
fresh: true,
68+
want: false,
69+
},
70+
}
71+
72+
for _, tt := range tests {
73+
t.Run(tt.name, func(t *testing.T) {
74+
got := shouldSendSIGUSR1(tt.old, tt.new, tt.fresh)
75+
if got != tt.want {
76+
t.Fatalf("got %v, want %v", got, tt.want)
77+
}
78+
})
79+
}
80+
}

internal/common/util.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ const dumpPath = "/tmp/goroutine-stacks.dump"
3434
// output didn't work.
3535
func StartDebugSignalHandlers() {
3636
go func() {
37-
if runtime.GOOS == "windows" {
38-
klog.Infof("Debug signal handlers are disabled on Windows")
39-
return
40-
}
4137
c := make(chan os.Signal, 1)
4238
signal.Notify(c, syscall.SIGUSR2)
4339
for range c {

0 commit comments

Comments
 (0)