package app import ( "context" "fmt" "io" "net/http" "strings" "sync/atomic" "time" "github.com/gochat/gochat/internal/config" "github.com/gochat/gochat/internal/database" basehandler "github.com/gochat/gochat/internal/handler" "github.com/gochat/gochat/internal/search" "github.com/redis/go-redis/v9" "gorm.io/gorm" ) func newReadinessChecks(cfg *config.Config, db *gorm.DB, rdb redis.UniversalClient, ready *atomic.Bool) []basehandler.DependencyCheck { latestMigration, latestMigrationErr := database.LatestVersion(cfg.Database.GetMigrationsPath()) checks := []basehandler.DependencyCheck{ {Name: "redis", Check: func(ctx context.Context) error { return rdb.Ping(ctx).Err() }}, {Name: "migrations", Check: func(ctx context.Context) error { if latestMigrationErr != nil { return latestMigrationErr } return database.CheckVersion(ctx, db, latestMigration) }}, {Name: "draining", Check: func(context.Context) error { if !ready.Load() { return fmt.Errorf("shutdown in progress") } return nil }}, } if !strings.EqualFold(cfg.Search.Engine, search.EngineMeilisearch) { return checks } searchClient := &http.Client{Timeout: time.Duration(cfg.Search.TimeoutSeconds) * time.Second} return append(checks, basehandler.DependencyCheck{Name: "search", Check: func(ctx context.Context) error { request, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(cfg.Search.Host, "/")+"/health", nil) if err != nil { return err } response, err := searchClient.Do(request) if err != nil { return err } defer response.Body.Close() _, _ = io.Copy(io.Discard, response.Body) if response.StatusCode != http.StatusOK { return fmt.Errorf("search health returned %s", response.Status) } return nil }}) }