@@ -96,8 +96,26 @@ func run() int {
96
96
ctx , cancelCtx := context .WithCancel (context .Background ())
97
97
defer cancelCtx ()
98
98
99
- heartbeat := icingaredis .NewHeartbeat (ctx , rc , logs .GetChildLogger ("heartbeat" ))
100
- ha := icingadb .NewHA (ctx , db , heartbeat , logs .GetChildLogger ("high-availability" ))
99
+ // Use dedicated connections for heartbeat and HA to ensure that heartbeats are always processed and
100
+ // the instance table is updated. Otherwise, the connections can be too busy due to the synchronization of
101
+ // configuration, status, history, etc., which can lead to handover / takeover loops because
102
+ // the heartbeat is not read while HA gets stuck when updating the instance table.
103
+ var heartbeat * icingaredis.Heartbeat
104
+ var ha * icingadb.HA
105
+ {
106
+ rc , err := cmd .Redis (logs .GetChildLogger ("redis" ))
107
+ if err != nil {
108
+ logger .Fatalf ("%+v" , errors .Wrap (err , "can't create Redis client from config" ))
109
+ }
110
+ heartbeat = icingaredis .NewHeartbeat (ctx , rc , logs .GetChildLogger ("heartbeat" ))
111
+
112
+ db , err := cmd .Database (logs .GetChildLogger ("database" ))
113
+ if err != nil {
114
+ logger .Fatalf ("%+v" , errors .Wrap (err , "can't create database connection pool from config" ))
115
+ }
116
+ defer db .Close ()
117
+ ha = icingadb .NewHA (ctx , db , heartbeat , logs .GetChildLogger ("high-availability" ))
118
+ }
101
119
// Closing ha on exit ensures that this instance retracts its heartbeat
102
120
// from the database so that another instance can take over immediately.
103
121
defer func () {
0 commit comments