refactor: implement worker pool pattern, add persistent task queue, and decouple target loading logic
This commit is contained in:
+11
-10
@@ -10,8 +10,8 @@ import (
|
||||
"github.com/hireme/hireme/internal/analyzer"
|
||||
"github.com/hireme/hireme/internal/config"
|
||||
"github.com/hireme/hireme/internal/db"
|
||||
"github.com/hireme/hireme/internal/service"
|
||||
"github.com/hireme/hireme/internal/ui"
|
||||
"github.com/hireme/hireme/internal/worker"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -42,7 +42,12 @@ func newRootCmd() *cobra.Command {
|
||||
if err != nil {
|
||||
return fmt.Errorf("fatal DB error: %w", err)
|
||||
}
|
||||
defer database.Close()
|
||||
defer func() { _ = database.Close() }()
|
||||
|
||||
// Load targets from YAML config if database is empty
|
||||
if err := database.LoadTargetsFromYAML(cfg.TargetConfig); err != nil {
|
||||
log.Printf("[Main] Target YAML loading status: %v", err)
|
||||
}
|
||||
|
||||
// Initialize LLM Analyzer
|
||||
llmAnalyzer, err := analyzer.NewAnalyzer(cfg)
|
||||
@@ -50,16 +55,12 @@ func newRootCmd() *cobra.Command {
|
||||
return fmt.Errorf("fatal Analyzer setup error: %w", err)
|
||||
}
|
||||
|
||||
// Initialize Pipeline Service
|
||||
pipeline := service.NewPipelineService(database, llmAnalyzer)
|
||||
|
||||
// Load targets from YAML config if database is empty
|
||||
if err := pipeline.LoadTargetsFromYAML(cfg.TargetConfig); err != nil {
|
||||
log.Printf("[Main] Target YAML loading status: %v", err)
|
||||
}
|
||||
// Initialize Worker Pool
|
||||
pool := worker.NewWorkerPool(database, llmAnalyzer, 3)
|
||||
pool.Start() // Auto start the worker pool
|
||||
|
||||
// Setup UI Server & Routes
|
||||
server := ui.NewServer(cfg, database, pipeline)
|
||||
server := ui.NewServer(cfg, database, pool)
|
||||
mux := http.NewServeMux()
|
||||
server.RegisterRoutes(mux)
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hireme/hireme/internal/analyzer"
|
||||
"github.com/hireme/hireme/internal/config"
|
||||
"github.com/hireme/hireme/internal/db"
|
||||
"github.com/hireme/hireme/internal/service"
|
||||
"github.com/hireme/hireme/internal/ui"
|
||||
)
|
||||
|
||||
func TestFullApplicationIntegration(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
dbPath := filepath.Join(tempDir, "test_hireme.db")
|
||||
yamlPath := filepath.Join(tempDir, "test_targets.yaml")
|
||||
|
||||
yamlContent := `targets:
|
||||
- name: "Google Software Engineer (Seattle)"
|
||||
target_url: "https://www.google.com/about/careers/applications/jobs/results/?employment_type=FULL_TIME&q=%22Software%20Engineer%22&location=Seattle%2C%20WA%2C%20USA&target_level=MID"
|
||||
platform: "google_jobs"
|
||||
is_active: true
|
||||
`
|
||||
if err := os.WriteFile(yamlPath, []byte(yamlContent), 0644); err != nil {
|
||||
t.Fatalf("failed to create test targets.yaml: %v", err)
|
||||
}
|
||||
|
||||
cfg := &config.Config{
|
||||
Port: "8080",
|
||||
DBPath: dbPath,
|
||||
TargetConfig: yamlPath,
|
||||
LLMProvider: "mock",
|
||||
}
|
||||
|
||||
database, err := db.InitDB(cfg.DBPath)
|
||||
if err != nil {
|
||||
t.Fatalf("InitDB failed: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
|
||||
llmAnalyzer, err := analyzer.NewAnalyzer(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("NewAnalyzer failed: %v", err)
|
||||
}
|
||||
|
||||
pipeline := service.NewPipelineService(database, llmAnalyzer)
|
||||
|
||||
// Verify target loading from YAML into SQLite
|
||||
if err := pipeline.LoadTargetsFromYAML(cfg.TargetConfig); err != nil {
|
||||
t.Fatalf("LoadTargetsFromYAML failed: %v", err)
|
||||
}
|
||||
|
||||
targets, err := database.GetAllTargets()
|
||||
if err != nil {
|
||||
t.Fatalf("GetAllTargets failed: %v", err)
|
||||
}
|
||||
if len(targets) != 1 {
|
||||
t.Errorf("expected 1 target from YAML, got %d", len(targets))
|
||||
}
|
||||
|
||||
// Verify jobs start empty on clean SQLite DB startup (0 jobs)
|
||||
jobs, err := database.GetJobsWithAnalysis()
|
||||
if err != nil {
|
||||
t.Fatalf("GetJobsWithAnalysis failed: %v", err)
|
||||
}
|
||||
if len(jobs) != 0 {
|
||||
t.Errorf("expected 0 jobs on clean startup, got %d", len(jobs))
|
||||
}
|
||||
|
||||
// Setup UI Server & routes
|
||||
server := ui.NewServer(cfg, database, pipeline)
|
||||
mux := http.NewServeMux()
|
||||
server.RegisterRoutes(mux)
|
||||
|
||||
// Test GET /
|
||||
reqRoot := httptest.NewRequest("GET", "/", nil)
|
||||
wRoot := httptest.NewRecorder()
|
||||
mux.ServeHTTP(wRoot, reqRoot)
|
||||
|
||||
if wRoot.Code != http.StatusOK {
|
||||
t.Errorf("expected 200 OK for GET /, got %d", wRoot.Code)
|
||||
}
|
||||
if !strings.Contains(wRoot.Body.String(), "Hireme") {
|
||||
t.Errorf("expected homepage HTML to contain 'Hireme'")
|
||||
}
|
||||
|
||||
// Test GET /targets
|
||||
reqTargets := httptest.NewRequest("GET", "/targets", nil)
|
||||
wTargets := httptest.NewRecorder()
|
||||
mux.ServeHTTP(wTargets, reqTargets)
|
||||
|
||||
if wTargets.Code != http.StatusOK {
|
||||
t.Errorf("expected 200 OK for GET /targets, got %d", wTargets.Code)
|
||||
}
|
||||
|
||||
// Test GET /jobs
|
||||
reqJobs := httptest.NewRequest("GET", "/jobs", nil)
|
||||
wJobs := httptest.NewRecorder()
|
||||
mux.ServeHTTP(wJobs, reqJobs)
|
||||
|
||||
if wJobs.Code != http.StatusOK {
|
||||
t.Errorf("expected 200 OK for GET /jobs, got %d", wJobs.Code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user