refactor: implement worker pool pattern, add persistent task queue, and decouple target loading logic

This commit is contained in:
2026-08-12 23:28:31 -07:00
parent 51b9468737
commit 890469fed8
18 changed files with 694 additions and 442 deletions
+30 -14
View File
@@ -180,16 +180,26 @@ const mainLayoutHTML = `{{ define "page" }}<!DOCTYPE html>
<span class="font-semibold text-indigo-300 uppercase">{{ .LLMProvider }}</span>
</div>
<button hx-post="/pipeline/run"
hx-target="#jobs-container"
hx-indicator="#run-spinner"
class="relative inline-flex items-center justify-center px-4 py-2 text-xs font-semibold text-white transition-all bg-indigo-600 rounded-lg shadow-md hover:bg-indigo-500 active:scale-95 shadow-indigo-500/25">
<svg id="run-spinner" class="htmx-indicator animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<span>⚡ Run Pipeline</span>
</button>
<div class="flex items-center space-x-2">
<button hx-post="/api/tasks/discover"
hx-swap="none"
hx-on::after-request="location.reload()"
class="relative inline-flex items-center justify-center px-3 py-1.5 text-xs font-semibold text-white transition-all bg-indigo-600 rounded-lg shadow-md hover:bg-indigo-500 active:scale-95 shadow-indigo-500/25">
<span>🔍 Discover Jobs</span>
</button>
<button hx-post="/api/tasks/clean"
hx-swap="none"
hx-on::after-request="location.reload()"
class="relative inline-flex items-center justify-center px-3 py-1.5 text-xs font-semibold text-white transition-all bg-red-600 rounded-lg shadow-md hover:bg-red-500 active:scale-95 shadow-red-500/25">
<span>🗑️ Clean Queue</span>
</button>
<button hx-post="/api/tasks/toggle"
hx-swap="none"
hx-on::after-request="location.reload()"
class="relative inline-flex items-center justify-center px-3 py-1.5 text-xs font-semibold text-white transition-all bg-emerald-600 rounded-lg shadow-md hover:bg-emerald-500 active:scale-95 shadow-emerald-500/25">
<span>⚙️ Toggle Workers</span>
</button>
</div>
</div>
</div>
</header>
@@ -454,9 +464,15 @@ const jobListHTML = `{{ define "jobs" }}
★ {{ printf "%.0f" .Analysis.Score }} Qualified
</span>
{{ else }}
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-[10px] font-semibold bg-rose-500/10 text-rose-400 border border-rose-500/20">
Not Qualified
</span>
<div class="flex flex-col gap-1 items-start">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-[10px] font-semibold bg-rose-500/10 text-rose-400 border border-rose-500/20">
Not Qualified
</span>
{{ $missing := parseJSON .Analysis.MissingHighlights }}
{{ if $missing }}
<span class="text-[9px] text-rose-400/80 line-clamp-2 max-w-[150px] leading-tight" title="{{ index $missing 0 }}">{{ index $missing 0 }}</span>
{{ end }}
</div>
{{ end }}
{{ else }}
<span class="text-slate-500 text-[11px]">-</span>
@@ -504,7 +520,7 @@ const jobListHTML = `{{ define "jobs" }}
{{ else }}
<tr>
<td colspan="7" class="px-4 py-8 text-center text-slate-500">
No job postings found yet. Click <strong>⚡ Run Pipeline</strong> to ingest jobs.
No job postings found yet. Click <strong>🔍 Discover Jobs</strong> to enqueue crawler tasks.
</td>
</tr>
{{ end }}