fix: delivery engine nil pointer crash on startup (closes #17)
Store the *database.Database wrapper instead of calling .DB() eagerly at construction time. The GORM *gorm.DB is only available after the database's OnStart hook runs, but the engine constructor runs during fx resolution (before OnStart). Accessing .DB() lazily via the wrapper avoids the nil pointer panic.
This commit is contained in:
parent
7f8469a0f2
commit
d4fbd6c110
@ -12,7 +12,6 @@ import (
|
||||
"time"
|
||||
|
||||
"go.uber.org/fx"
|
||||
"gorm.io/gorm"
|
||||
"sneak.berlin/go/webhooker/internal/database"
|
||||
"sneak.berlin/go/webhooker/internal/logger"
|
||||
)
|
||||
@ -46,7 +45,7 @@ type EngineParams struct {
|
||||
|
||||
// Engine processes queued deliveries in the background.
|
||||
type Engine struct {
|
||||
db *gorm.DB
|
||||
database *database.Database
|
||||
log *slog.Logger
|
||||
client *http.Client
|
||||
cancel context.CancelFunc
|
||||
@ -56,7 +55,7 @@ type Engine struct {
|
||||
// New creates and registers the delivery engine with the fx lifecycle.
|
||||
func New(lc fx.Lifecycle, params EngineParams) *Engine {
|
||||
e := &Engine{
|
||||
db: params.DB.DB(),
|
||||
database: params.DB,
|
||||
log: params.Logger.Get(),
|
||||
client: &http.Client{
|
||||
Timeout: httpClientTimeout,
|
||||
@ -110,7 +109,7 @@ func (e *Engine) run(ctx context.Context) {
|
||||
|
||||
func (e *Engine) processPending(ctx context.Context) {
|
||||
var deliveries []database.Delivery
|
||||
result := e.db.
|
||||
result := e.database.DB().
|
||||
Where("status IN ?", []database.DeliveryStatus{
|
||||
database.DeliveryStatusPending,
|
||||
database.DeliveryStatusRetrying,
|
||||
@ -196,13 +195,13 @@ func (e *Engine) deliverRetry(_ context.Context, d *database.Delivery) {
|
||||
|
||||
// Determine attempt number from existing results
|
||||
var resultCount int64
|
||||
e.db.Model(&database.DeliveryResult{}).Where("delivery_id = ?", d.ID).Count(&resultCount)
|
||||
e.database.DB().Model(&database.DeliveryResult{}).Where("delivery_id = ?", d.ID).Count(&resultCount)
|
||||
attemptNum := int(resultCount) + 1
|
||||
|
||||
// Check if we should wait before retrying (exponential backoff)
|
||||
if attemptNum > 1 {
|
||||
var lastResult database.DeliveryResult
|
||||
lookupErr := e.db.Where("delivery_id = ?", d.ID).Order("created_at DESC").First(&lastResult).Error
|
||||
lookupErr := e.database.DB().Where("delivery_id = ?", d.ID).Order("created_at DESC").First(&lastResult).Error
|
||||
if lookupErr == nil {
|
||||
shift := attemptNum - 2
|
||||
if shift > 30 {
|
||||
@ -330,7 +329,7 @@ func (e *Engine) recordResult(d *database.Delivery, attemptNum int, success bool
|
||||
Duration: durationMs,
|
||||
}
|
||||
|
||||
if err := e.db.Create(result).Error; err != nil {
|
||||
if err := e.database.DB().Create(result).Error; err != nil {
|
||||
e.log.Error("failed to record delivery result",
|
||||
"delivery_id", d.ID,
|
||||
"error", err,
|
||||
@ -339,7 +338,7 @@ func (e *Engine) recordResult(d *database.Delivery, attemptNum int, success bool
|
||||
}
|
||||
|
||||
func (e *Engine) updateDeliveryStatus(d *database.Delivery, status database.DeliveryStatus) {
|
||||
if err := e.db.Model(d).Update("status", status).Error; err != nil {
|
||||
if err := e.database.DB().Model(d).Update("status", status).Error; err != nil {
|
||||
e.log.Error("failed to update delivery status",
|
||||
"delivery_id", d.ID,
|
||||
"status", status,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user