feat(coordinator): worker registry, API contract, logging & DB retry
Align the coordinator with the master PLAN.md (CTX-00, CTX-04) and harden process startup. - CTX-00: freeze docs/api-contract.md as the v1 source of truth for the Go coordinator and Python worker. - CTX-04: worker registry — workers table (migration 0002), domain.Worker, RegisterWorker use case, WorkerRepository, and POST /workers/register. - Contract alignment: claim uses `capabilities` (was `workloads`), COORDINATOR_TOKEN env (WORKER_AUTH_TOKEN kept as fallback), and GET /health now reports database readiness (503 when the DB is down). - Logging: logs are teed to stdout and an optional rotated file (LOG_FILE) via lumberjack, so they survive a container rebuild. - Startup resilience: the initial DB connection is retried with backoff, so the coordinator waits for Postgres to boot instead of crash-looping.
This commit is contained in:
@@ -21,6 +21,11 @@ type ChunkInput struct {
|
||||
MaxAttempts int
|
||||
}
|
||||
|
||||
type RegisterWorkerInput struct {
|
||||
Name string
|
||||
Capabilities []string
|
||||
}
|
||||
|
||||
type ClaimTaskInput struct {
|
||||
WorkerID string
|
||||
Workloads []string
|
||||
|
||||
@@ -62,6 +62,12 @@ type JobRepository interface {
|
||||
UpdateStatus(ctx context.Context, id uuid.UUID, status domain.JobStatus, completedAt *time.Time) error
|
||||
}
|
||||
|
||||
// WorkerRepository persists the worker registry.
|
||||
type WorkerRepository interface {
|
||||
Insert(ctx context.Context, w *domain.Worker) error
|
||||
Get(ctx context.Context, id uuid.UUID) (*domain.Worker, error)
|
||||
}
|
||||
|
||||
// TxManager runs a function inside one database transaction. The transaction
|
||||
// travels in the context, so repositories pick it up without this port ever
|
||||
// mentioning pgx.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/emil28092005/SciMesh/coordinator/internal/domain"
|
||||
)
|
||||
|
||||
// RegisterWorker records a worker in the registry and hands back its identity.
|
||||
type RegisterWorker struct {
|
||||
workers WorkerRepository
|
||||
clk Clock
|
||||
}
|
||||
|
||||
func NewRegisterWorker(workers WorkerRepository, clk Clock) *RegisterWorker {
|
||||
return &RegisterWorker{workers: workers, clk: clk}
|
||||
}
|
||||
|
||||
func (uc *RegisterWorker) Execute(ctx context.Context, in RegisterWorkerInput) (*domain.Worker, error) {
|
||||
w, err := domain.NewWorker(in.Name, in.Capabilities, uc.clk.Now())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := uc.workers.Insert(ctx, w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return w, nil
|
||||
}
|
||||
Reference in New Issue
Block a user