mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 04:01:34 +00:00
* docs: Update TASKS.md and PRODUCTION-TASKS.md to reflect current codebase state (December 2024 audit) * refactor: Unify all commands into a single Cobra CLI - Refactor cmd/api/main.go into 'tercul serve' command - Refactor cmd/worker/main.go into 'tercul worker' command - Refactor cmd/tools/enrich/main.go into 'tercul enrich' command - Add 'tercul bleve-migrate' command for Bleve index migration - Extract common initialization logic into cmd/cli/internal/bootstrap - Update Dockerfile to build unified CLI - Update README with new CLI usage This consolidates all entry points into a single, maintainable CLI structure. * fix: Fix CodeQL workflow and add comprehensive test coverage - Fix Go version mismatch by setting up Go before CodeQL init - Add Go version verification step - Improve error handling for code scanning upload - Add comprehensive test suite for CLI commands: - Bleve migration tests with in-memory indexes - Edge case tests (empty data, large batches, errors) - Command-level integration tests - Bootstrap initialization tests - Optimize tests to use in-memory Bleve indexes for speed - Add test tags for skipping slow tests in short mode - Update workflow documentation Test coverage: 18.1% with 806 lines of test code All tests passing in short mode * fix: Fix test workflow and Bleve test double-close panic - Add POSTGRES_USER to PostgreSQL service configuration in test workflow - Fix TestInitBleveIndex double-close panic by removing defer before explicit close - Test now passes successfully Fixes failing Unit Tests workflow in PR #64
111 lines
2.9 KiB
Go
111 lines
2.9 KiB
Go
package commands
|
|
|
|
import (
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"tercul/cmd/cli/internal/bootstrap"
|
|
"tercul/internal/jobs/sync"
|
|
"tercul/internal/platform/config"
|
|
"tercul/internal/platform/db"
|
|
app_log "tercul/internal/platform/log"
|
|
|
|
"github.com/hibiken/asynq"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// NewWorkerCommand creates a new Cobra command for running background workers
|
|
func NewWorkerCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "worker",
|
|
Short: "Start the Tercul background worker",
|
|
Long: `Start the Tercul background worker to process async jobs including:
|
|
- Sync jobs (Weaviate indexing, etc.)
|
|
- Linguistic analysis jobs
|
|
- Trending calculation jobs`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
// Load configuration
|
|
cfg, err := config.LoadConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Initialize logger
|
|
app_log.Init("tercul-worker", cfg.Environment)
|
|
app_log.Info("Starting Tercul worker...")
|
|
|
|
// Initialize database connection
|
|
database, err := db.InitDB(cfg, nil) // No metrics needed for the worker
|
|
if err != nil {
|
|
app_log.Fatal(err, "Failed to initialize database")
|
|
}
|
|
defer func() {
|
|
if err := db.Close(database); err != nil {
|
|
app_log.Error(err, "Error closing database")
|
|
}
|
|
}()
|
|
|
|
// Initialize Weaviate client
|
|
weaviateClient, err := bootstrap.NewWeaviateClient(cfg)
|
|
if err != nil {
|
|
app_log.Fatal(err, "Failed to create weaviate client")
|
|
}
|
|
|
|
// Initialize Asynq client and server
|
|
redisConnection := asynq.RedisClientOpt{Addr: cfg.RedisAddr}
|
|
asynqClient := asynq.NewClient(redisConnection)
|
|
defer func() {
|
|
if err := asynqClient.Close(); err != nil {
|
|
app_log.Error(err, "Error closing asynq client")
|
|
}
|
|
}()
|
|
|
|
srv := asynq.NewServer(
|
|
redisConnection,
|
|
asynq.Config{
|
|
Concurrency: 10, // Example concurrency
|
|
Queues: map[string]int{
|
|
"critical": 6,
|
|
"default": 3,
|
|
"low": 1,
|
|
},
|
|
},
|
|
)
|
|
|
|
// Create SyncJob with all dependencies
|
|
syncJob := sync.NewSyncJob(database, asynqClient, cfg, weaviateClient)
|
|
|
|
// Create a new ServeMux for routing jobs
|
|
mux := asynq.NewServeMux()
|
|
|
|
// Register all job handlers
|
|
sync.RegisterQueueHandlers(mux, syncJob)
|
|
// Placeholder for other job handlers that might be added in the future
|
|
// linguistics.RegisterLinguisticHandlers(mux, linguisticJob)
|
|
// trending.RegisterTrendingHandlers(mux, analyticsService)
|
|
|
|
// Start the server in a goroutine
|
|
go func() {
|
|
if err := srv.Run(mux); err != nil {
|
|
app_log.Fatal(err, "Could not run asynq server")
|
|
}
|
|
}()
|
|
|
|
app_log.Info("Worker started successfully.")
|
|
|
|
// Wait for interrupt signal to gracefully shutdown the server
|
|
quit := make(chan os.Signal, 1)
|
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|
<-quit
|
|
|
|
app_log.Info("Shutting down worker...")
|
|
srv.Shutdown()
|
|
app_log.Info("Worker shut down successfully.")
|
|
return nil
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|