feat(master): route jobs to agents and reconcile them on reconnect (#7)

This commit is contained in:
2026-10-12 18:42:30 +02:00
parent 574f425267
commit 68e5c33722
9 changed files with 653 additions and 11 deletions
+38
View File
@@ -3,6 +3,7 @@ package hub
import (
"bytes"
"context"
"fmt"
"io"
"log/slog"
"net/http"
@@ -35,6 +36,18 @@ type fakeStore struct {
// revokeFromLookup, when > 0, makes AgentByTokenHash return the agent as
// revoked from that (1-based) lookup onwards.
revokeFromLookup int
// Job calls, recorded; the *Result fields script the answers.
lostCalls [][]int64
lostResult []int64
lostErr error
lostGate chan struct{} // when set, FailLostJobs blocks until it is closed
progress []string // "agent|job|chunk"
progressOK bool
finishes []model.JobFinish
finishAgents []int64
finishOK bool
finishErr error
}
func newFakeStore(agents ...model.Agent) *fakeStore {
@@ -94,6 +107,31 @@ func (f *fakeStore) MarkSeen(_ context.Context, id int64, _ time.Time) error {
return nil
}
func (f *fakeStore) FailLostJobs(_ context.Context, _ int64, known []int64, _ time.Time) ([]int64, error) {
if f.lostGate != nil {
<-f.lostGate
}
f.mu.Lock()
defer f.mu.Unlock()
f.lostCalls = append(f.lostCalls, known)
return f.lostResult, f.lostErr
}
func (f *fakeStore) JobProgress(_ context.Context, agentID, jobID int64, chunk string, _ time.Time) (bool, error) {
f.mu.Lock()
defer f.mu.Unlock()
f.progress = append(f.progress, fmt.Sprintf("%d|%d|%s", agentID, jobID, chunk))
return f.progressOK, nil
}
func (f *fakeStore) FinishJob(_ context.Context, agentID, _ int64, fin model.JobFinish) (bool, error) {
f.mu.Lock()
defer f.mu.Unlock()
f.finishAgents = append(f.finishAgents, agentID)
f.finishes = append(f.finishes, fin)
return f.finishOK, f.finishErr
}
func (f *fakeStore) count(get func(*fakeStore) int) func() int {
return func() int {
f.mu.Lock()