aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--backend/db/query.sql.go22
-rw-r--r--backend/game/hub.go29
-rw-r--r--backend/query.sql14
-rw-r--r--worker/exec.go2
-rw-r--r--worker/models.go2
5 files changed, 64 insertions, 5 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;
diff --git a/worker/exec.go b/worker/exec.go
index 10bc99a..fb238c3 100644
--- a/worker/exec.go
+++ b/worker/exec.go
@@ -77,7 +77,7 @@ func convertCommandErrorToResultType(err error) string {
if err == context.DeadlineExceeded {
return resultTimeout
} else {
- return resultFailure
+ return resultRuntimeError
}
} else {
return resultSuccess
diff --git a/worker/models.go b/worker/models.go
index a7310bd..c60002c 100644
--- a/worker/models.go
+++ b/worker/models.go
@@ -7,7 +7,7 @@ import (
const (
resultSuccess = "success"
- resultFailure = "failure"
+ resultRuntimeError = "runtime_error"
resultTimeout = "timeout"
resultInternalError = "internal_error"
)