| 235 | } |
| 236 | |
| 237 | func (app *BootstrapApp) heartbeatRoutine() { |
| 238 | ticker := time.NewTicker(time.Duration(12) * time.Hour) |
| 239 | defer ticker.Stop() |
| 240 | |
| 241 | type heartbeat struct { |
| 242 | UUID string `json:"uuid"` |
| 243 | Version string `json:"version"` |
| 244 | } |
| 245 | |
| 246 | var body heartbeat |
| 247 | |
| 248 | body.UUID = app.context.uuid |
| 249 | body.Version = config.Version |
| 250 | |
| 251 | bodyJson, err := json.Marshal(body) |
| 252 | |
| 253 | if err != nil { |
| 254 | tlog.App.Error().Err(err).Msg("Failed to marshal heartbeat body") |
| 255 | return |
| 256 | } |
| 257 | |
| 258 | client := &http.Client{ |
| 259 | Timeout: 30 * time.Second, // The server should never take more than 30 seconds to respond |
| 260 | } |
| 261 | |
| 262 | heartbeatURL := config.ApiServer + "/v1/instances/heartbeat" |
| 263 | |
| 264 | for range ticker.C { |
| 265 | tlog.App.Debug().Msg("Sending heartbeat") |
| 266 | |
| 267 | req, err := http.NewRequest(http.MethodPost, heartbeatURL, bytes.NewReader(bodyJson)) |
| 268 | |
| 269 | if err != nil { |
| 270 | tlog.App.Error().Err(err).Msg("Failed to create heartbeat request") |
| 271 | continue |
| 272 | } |
| 273 | |
| 274 | req.Header.Add("Content-Type", "application/json") |
| 275 | |
| 276 | res, err := client.Do(req) |
| 277 | |
| 278 | if err != nil { |
| 279 | tlog.App.Error().Err(err).Msg("Failed to send heartbeat") |
| 280 | continue |
| 281 | } |
| 282 | |
| 283 | res.Body.Close() |
| 284 | |
| 285 | if res.StatusCode != 200 && res.StatusCode != 201 { |
| 286 | tlog.App.Debug().Str("status", res.Status).Msg("Heartbeat returned non-200/201 status") |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | func (app *BootstrapApp) dbCleanupRoutine(queries *repository.Queries) { |
| 292 | ticker := time.NewTicker(time.Duration(30) * time.Minute) |