init
This commit is contained in:
90
internal/reconciler/reconciler.go
Normal file
90
internal/reconciler/reconciler.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package reconciler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"deployment-manager/internal/db"
|
||||
"deployment-manager/internal/model"
|
||||
)
|
||||
|
||||
type Reconciler struct {
|
||||
repoStore *db.RepoStore
|
||||
jobChan chan<- int64
|
||||
ticker *time.Ticker
|
||||
}
|
||||
|
||||
func NewReconciler(database *sql.DB, jobChan chan<- int64, tickInterval time.Duration) *Reconciler {
|
||||
return &Reconciler{
|
||||
repoStore: db.NewRepoStore(database),
|
||||
jobChan: jobChan,
|
||||
ticker: time.NewTicker(tickInterval),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) Run(ctx context.Context) {
|
||||
log.Println("Reconciler started")
|
||||
|
||||
defer r.ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Println("Reconciler shutting down")
|
||||
return
|
||||
|
||||
case <-r.ticker.C:
|
||||
if err := r.reconcile(ctx); err != nil {
|
||||
log.Printf("Reconciliation error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) reconcile(ctx context.Context) error {
|
||||
// Find repos that need to be deployed
|
||||
repos, err := r.repoStore.ListByStatus(model.StatusNeedToDeploy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Enqueue jobs for repos that need deployment
|
||||
for _, repo := range repos {
|
||||
select {
|
||||
case r.jobChan <- repo.ID:
|
||||
log.Printf("Enqueued deployment job for repo %d", repo.ID)
|
||||
default:
|
||||
log.Printf("Job queue full, skipping repo %d", repo.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Find repos that are in error state and might need retry
|
||||
errorRepos, err := r.repoStore.ListByStatus(model.StatusError)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Simple retry logic: retry errors older than 5 minutes
|
||||
for _, repo := range errorRepos {
|
||||
if time.Since(repo.UpdatedAt) > 5*time.Minute {
|
||||
// Reset to need_to_deploy for retry
|
||||
repo.Status = model.StatusNeedToDeploy
|
||||
repo.LastError = nil
|
||||
if err := r.repoStore.Update(repo); err != nil {
|
||||
log.Printf("Failed to reset repo %d for retry: %v", repo.ID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
select {
|
||||
case r.jobChan <- repo.ID:
|
||||
log.Printf("Enqueued retry job for repo %d", repo.ID)
|
||||
default:
|
||||
log.Printf("Job queue full, skipping retry for repo %d", repo.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user