a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
at main 2.5 kB view raw
1package runner 2 3import ( 4 "context" 5 "log" 6 "sync" 7 "time" 8 9 "battleship-arena/internal/storage" 10) 11 12var workerMutex sync.Mutex 13 14func StartWorker(ctx context.Context, uploadDir string, broadcastFunc func(string, int, int, time.Time, []string), notifyFunc func(), completeFunc func(), statusFunc func(string, string, string)) { 15 ticker := time.NewTicker(10 * time.Second) 16 defer ticker.Stop() 17 18 go func() { 19 if err := processSubmissionsWithLock(uploadDir, broadcastFunc, notifyFunc, completeFunc, statusFunc); err != nil { 20 log.Printf("Worker error (submissions): %v", err) 21 } 22 }() 23 24 for { 25 select { 26 case <-ctx.Done(): 27 return 28 case <-ticker.C: 29 go func() { 30 if err := processSubmissionsWithLock(uploadDir, broadcastFunc, notifyFunc, completeFunc, statusFunc); err != nil { 31 log.Printf("Worker error (submissions): %v", err) 32 } 33 }() 34 } 35 } 36} 37 38func processSubmissionsWithLock(uploadDir string, broadcastFunc func(string, int, int, time.Time, []string), notifyFunc func(), completeFunc func(), statusFunc func(string, string, string)) error { 39 if !workerMutex.TryLock() { 40 // Silently skip if worker is already running 41 return nil 42 } 43 defer workerMutex.Unlock() 44 45 return ProcessSubmissions(uploadDir, broadcastFunc, notifyFunc, completeFunc, statusFunc) 46} 47 48func ProcessSubmissions(uploadDir string, broadcastFunc func(string, int, int, time.Time, []string), notifyFunc func(), completeFunc func(), statusFunc func(string, string, string)) error { 49 submissions, err := storage.GetPendingSubmissions() 50 if err != nil { 51 return err 52 } 53 54 // Only do work if there are pending submissions 55 if len(submissions) == 0 { 56 return nil 57 } 58 59 for _, sub := range submissions { 60 log.Printf("⚙️ Compiling %s (%s)", sub.Username, sub.Filename) 61 statusFunc(sub.Username, "compiling", "") 62 63 if err := CompileSubmission(sub, uploadDir); err != nil { 64 log.Printf("❌ Compilation failed for %s: %v", sub.Username, err) 65 storage.UpdateSubmissionStatusWithMessage(sub.ID, "compilation_failed", err.Error()) 66 statusFunc(sub.Username, "compilation_failed", err.Error()) 67 notifyFunc() 68 continue 69 } 70 71 log.Printf("✓ Compiled %s", sub.Username) 72 storage.UpdateSubmissionStatus(sub.ID, "completed") 73 statusFunc(sub.Username, "running_matches", "") 74 75 RunRoundRobinMatches(sub, uploadDir, broadcastFunc) 76 statusFunc(sub.Username, "completed", "") 77 notifyFunc() 78 } 79 80 // Check if queue is now empty 81 queuedPlayers := storage.GetQueuedPlayerNames() 82 if len(queuedPlayers) == 0 { 83 completeFunc() 84 } 85 86 return nil 87}