diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-08-08 03:57:16 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-08-08 04:02:37 +0900 |
| commit | a062af23b2e72c38b667e969652aefcf2238dc1b (patch) | |
| tree | cbcaa732e083d9465e11396ffc555ba08e0f87ef /backend | |
| parent | 4eb7e89d6a77a4434bd087fbb86873521d30a8f5 (diff) | |
| download | phperkaigi-2025-albatross-a062af23b2e72c38b667e969652aefcf2238dc1b.tar.gz phperkaigi-2025-albatross-a062af23b2e72c38b667e969652aefcf2238dc1b.tar.zst phperkaigi-2025-albatross-a062af23b2e72c38b667e969652aefcf2238dc1b.zip | |
feat(backend): aggregate testcase results
Diffstat (limited to 'backend')
| -rw-r--r-- | backend/db/query.sql.go | 22 | ||||
| -rw-r--r-- | backend/game/hub.go | 29 | ||||
| -rw-r--r-- | backend/query.sql | 14 |
3 files changed, 62 insertions, 3 deletions
diff --git a/backend/db/query.sql.go b/backend/db/query.sql.go index cfb97fd..5475067 100644 --- a/backend/db/query.sql.go +++ b/backend/db/query.sql.go @@ -11,6 +11,28 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const aggregateTestcaseResults = `-- name: AggregateTestcaseResults :one +SELECT + CASE + WHEN COUNT(CASE WHEN r.status IS NULL THEN 1 END) > 0 THEN 'running' + WHEN COUNT(CASE WHEN r.status = 'internal_error' THEN 1 END) > 0 THEN 'internal_error' + WHEN COUNT(CASE WHEN r.status = 'timeout' THEN 1 END) > 0 THEN 'timeout' + WHEN COUNT(CASE WHEN r.status = 'runtime_error' THEN 1 END) > 0 THEN 'runtime_error' + WHEN COUNT(CASE WHEN r.status = 'wrong_answer' THEN 1 END) > 0 THEN 'wrong_answer' + ELSE 'success' + END AS status +FROM testcases +LEFT JOIN testcase_results AS r ON testcases.testcase_id = r.testcase_id +WHERE r.submission_id = $1 +` + +func (q *Queries) AggregateTestcaseResults(ctx context.Context, submissionID int32) (string, error) { + row := q.db.QueryRow(ctx, aggregateTestcaseResults, submissionID) + var status string + err := row.Scan(&status) + return status, err +} + const createSubmission = `-- name: CreateSubmission :one INSERT INTO submissions (game_id, user_id, code, code_size) VALUES ($1, $2, $3, $4) diff --git a/backend/game/hub.go b/backend/game/hub.go index d17ff7c..11a466b 100644 --- a/backend/game/hub.go +++ b/backend/game/hub.go @@ -270,7 +270,17 @@ func (hub *gameHub) processTaskResults() { // TODO: broadcast to watchers } case *taskqueue.TaskResultRunTestcase: - err := hub.processTaskResultRunTestcase(taskResult) + var err error + err = hub.processTaskResultRunTestcase(taskResult) + _ = err // TODO: handle err? + aggregatedStatus, err := hub.q.AggregateTestcaseResults(hub.ctx, int32(taskResult.TaskPayload.SubmissionID)) + _ = err // TODO: handle err? + err = hub.q.CreateSubmissionResult(hub.ctx, db.CreateSubmissionResultParams{ + SubmissionID: int32(taskResult.TaskPayload.SubmissionID), + Status: aggregatedStatus, + Stdout: "", + Stderr: "", + }) if err != nil { for player := range hub.players { if player.playerID != taskResult.TaskPayload.UserID() { @@ -280,13 +290,26 @@ func (hub *gameHub) processTaskResults() { Type: playerMessageTypeS2CExecResult, Data: playerMessageS2CExecResultPayload{ Score: nil, - Status: api.GamePlayerMessageS2CExecResultPayloadStatus(err.Status), + Status: api.GamePlayerMessageS2CExecResultPayloadStatus("internal_error"), }, } } // TODO: broadcast to watchers + continue + } + for player := range hub.players { + if player.playerID != taskResult.TaskPayload.UserID() { + continue + } + player.s2cMessages <- &playerMessageS2CExecResult{ + Type: playerMessageTypeS2CExecResult, + Data: playerMessageS2CExecResultPayload{ + Score: nil, + Status: api.GamePlayerMessageS2CExecResultPayloadStatus(aggregatedStatus), + }, + } + // TODO: broadcast to watchers } - // TODO: aggregate results of testcases default: panic("unexpected task result type") } diff --git a/backend/query.sql b/backend/query.sql index 0d32944..e767746 100644 --- a/backend/query.sql +++ b/backend/query.sql @@ -75,3 +75,17 @@ VALUES ($1, $2, $3, $4); -- name: CreateTestcaseResult :exec INSERT INTO testcase_results (submission_id, testcase_id, status, stdout, stderr) VALUES ($1, $2, $3, $4, $5); + +-- name: AggregateTestcaseResults :one +SELECT + CASE + WHEN COUNT(CASE WHEN r.status IS NULL THEN 1 END) > 0 THEN 'running' + WHEN COUNT(CASE WHEN r.status = 'internal_error' THEN 1 END) > 0 THEN 'internal_error' + WHEN COUNT(CASE WHEN r.status = 'timeout' THEN 1 END) > 0 THEN 'timeout' + WHEN COUNT(CASE WHEN r.status = 'runtime_error' THEN 1 END) > 0 THEN 'runtime_error' + WHEN COUNT(CASE WHEN r.status = 'wrong_answer' THEN 1 END) > 0 THEN 'wrong_answer' + ELSE 'success' + END AS status +FROM testcases +LEFT JOIN testcase_results AS r ON testcases.testcase_id = r.testcase_id +WHERE r.submission_id = $1; |
