Skip to content

Commit d427e4c

Browse files
working
1 parent ee25f8e commit d427e4c

3 files changed

Lines changed: 117 additions & 30 deletions

File tree

index.html

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,10 @@ <h3 style="margin-top:0; color: #ff5555;">Details</h3><pre id="modalText"></pre>
245245

246246
<!-- Admin View: Input Generator -->
247247
<div class="admin-section">
248-
<h3 style="margin:0 0 10px 0; color:var(--accent-admin);">Input Generator</h3>
248+
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;">
249+
<h3 style="margin:0; color:var(--accent-admin);">Input Generator</h3>
250+
<button onclick="clearPackets()" style="background:transparent; border:1px solid #552222; color:#ff5555; cursor:pointer; font-size:10px; padding:2px 8px; border-radius:4px; transition: 0.3s;" onmouseover="this.style.background='#331111'" onmouseout="this.style.background='transparent'">Clear Packets</button>
251+
</div>
249252
<div>
250253
<label>Language</label>
251254
<select id="gen-lang"><option value="python3">Python</option></select>
@@ -690,7 +693,8 @@ <h2 id="main-title" style="margin:0; font-size: 18px; color: var(--accent);">Sol
690693
out.innerHTML = `<div class="stderr">Generation Runtime Error:</div><pre style="color:#aaa">${sub.stderr}</pre>`;
691694
} else {
692695
try {
693-
const resArr = JSON.parse(sub.stdout || "[]");
696+
let resArrRaw = JSON.parse(sub.stdout || "[]");
697+
let resArr = Array.isArray(resArrRaw) ? resArrRaw : (resArrRaw.generated || []);
694698
let html = `<div style="color:var(--accent-admin); font-weight:bold; margin-bottom:10px;">Generated ${resArr.length} Test Cases:</div>`;
695699
html += `<div style="max-height:150px; overflow-y:auto; border:1px solid #333; padding:10px; border-radius:4px;">`;
696700

@@ -894,6 +898,12 @@ <h2 id="main-title" style="margin:0; font-size: 18px; color: var(--accent);">Sol
894898
loadQuestion(sub.question_id, null, false);
895899
}
896900
}
901+
function clearPackets() {
902+
if (confirm("Clear all generated packets? This will remove all temporary inputs from the list below.")) {
903+
adminInputPackets = [];
904+
renderInputPackets();
905+
}
906+
}
897907
</script>
898908
</body>
899909
</html>

internal/worker/worker.go

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"encoding/json"
1111
"fmt"
1212
"strconv"
13+
"strings"
1314
"time"
1415
"github.com/redis/go-redis/v9"
1516
"github.com/zekrotja/rogu/log"
@@ -75,8 +76,8 @@ func (w *Worker) Start() {
7576
cStdErr := make(chan []byte)
7677
cStop := make(chan bool, 1)
7778

78-
stdOutBuf := cappedbuffer.New([]byte{}, 10*1024)
79-
stdErrBuf := cappedbuffer.New([]byte{}, 10*1024)
79+
stdOutBuf := cappedbuffer.New([]byte{}, 100*1024)
80+
stdErrBuf := cappedbuffer.New([]byte{}, 20*1024)
8081

8182
go func() {
8283
for {
@@ -119,32 +120,59 @@ func (w *Worker) Start() {
119120
stderr = "Failed to parse generated inputs as JSON array of strings.\nOutput was:\n" + output
120121
}
121122
} else {
122-
var genResult struct {
123-
Generated []models.TestCase `json:"generated"`
123+
jsonStr := strings.TrimSpace(output)
124+
// If the full output isn't valid JSON, scan from last line backwards
125+
if !json.Valid([]byte(jsonStr)) {
126+
lines := strings.Split(jsonStr, "\n")
127+
for i := len(lines) - 1; i >= 0; i-- {
128+
line := strings.TrimSpace(lines[i])
129+
if len(line) > 0 && json.Valid([]byte(line)) {
130+
jsonStr = line
131+
break
132+
}
133+
}
124134
}
125-
if jsonErr := json.Unmarshal([]byte(output), &genResult); jsonErr == nil && len(genResult.Generated) > 0 {
126-
status = "SUCCESS"
127-
passedCount = totalTestCases
128-
} else {
135+
136+
parsed := false
137+
138+
// 1. Try as Admin Test Generation Result (Object with "generated" key)
139+
if strings.Contains(jsonStr, "\"generated\"") {
140+
var genResult struct {
141+
Generated []models.TestCase `json:"generated"`
142+
}
143+
if err := json.Unmarshal([]byte(jsonStr), &genResult); err == nil {
144+
status = "SUCCESS"
145+
passedCount = totalTestCases
146+
output = jsonStr
147+
parsed = true
148+
}
149+
}
150+
151+
// 2. Try as Standard Solver Result (Array of TestResults)
152+
if !parsed {
129153
var results []models.TestResult
130-
if jsonErr := json.Unmarshal([]byte(output), &results); jsonErr == nil {
131-
if len(results) == 0 {
132-
status = "SUCCESS"
133-
passedCount = totalTestCases
134-
} else {
154+
if err := json.Unmarshal([]byte(jsonStr), &results); err == nil {
155+
output = jsonStr
156+
if len(results) > 0 {
135157
failure := results[0]
136158
status = "FAILURE"
137159
if idVal, err := strconv.Atoi(failure.TestCaseID); err == nil {
138160
passedCount = idVal - 1
139161
}
140-
stderr = fmt.Sprintf("Failed Case %s:\n\nExpected Output:\n%s\n\nActual Output:\n%s",
162+
stderr = fmt.Sprintf("Failed Case %s:\n\nExpected Output:\n%s\n\nActual Output:\n%s",
141163
failure.TestCaseID, failure.Expected, failure.Actual)
164+
} else {
165+
status = "SUCCESS"
166+
passedCount = totalTestCases
142167
}
143-
} else {
144-
status = "ERROR"
145-
stderr += "\nJudge Error: Output format invalid (Output limit might be exceeded)."
168+
parsed = true
146169
}
147170
}
171+
172+
if !parsed {
173+
status = "ERROR"
174+
stderr += fmt.Sprintf("\nJudge Error: Output format invalid.\nExtracted: %s\nOriginal: %s", jsonStr, output)
175+
}
148176
}
149177
}
150178

@@ -238,13 +266,10 @@ def run():
238266
results = []
239267
is_gen = len(tests) > 0 and tests[0].get("expected_output") == "__GENERATE__"
240268
failed_result = None
241-
for t in tests:
242-
res = {"id": t["id"], "status": "FAILED", "expected": t["expected_output"], "actual": ""}
269+
for i, t in enumerate(tests):
270+
res = {"test_case_id": str(i+1), "status": "FAILED", "expected": t["expected_output"], "actual": ""}
243271
try:
244272
inp = t["input"]
245-
try:
246-
if "." not in inp: inp = int(inp)
247-
except: pass
248273
val = solve(inp)
249274
actual = str(val)
250275
if is_gen:
@@ -253,6 +278,9 @@ def run():
253278
res["actual"] = actual
254279
if actual.strip() == t["expected_output"].strip(): res["status"] = "PASSED"
255280
except Exception as e:
281+
if is_gen:
282+
results.append({"input": str(t["input"]), "expected_output": "ERROR: " + str(e)})
283+
continue
256284
res["status"] = "ERROR"
257285
res["actual"] = str(e)
258286
if not is_gen and res["status"] != "PASSED":
@@ -263,7 +291,7 @@ def run():
263291
elif failed_result: print(json.dumps([failed_result]))
264292
else: print(json.dumps([]))
265293
except Exception as e:
266-
print(json.dumps([{"id": "0", "status": "ERROR", "actual": str(e), "expected": ""}]))
294+
print(json.dumps([{"test_case_id": "0", "status": "ERROR", "actual": str(e), "expected": ""}]))
267295
if __name__ == "__main__": run()
268296
`
269297

server.log

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,55 @@
11
nohup: ignoring input
2-
2026-03-25T00:49:26+05:30 INFO Connected to Postgres
3-
2026-03-25T00:49:26+05:30 INFO Connected to Redis
4-
2026-03-25T00:49:26+05:30 INFO Starting Worker Pool (Min: 1, Max: 6)
5-
2026-03-25T00:49:26+05:30 INFO Code Runner Started on port :8080. Workers: Min=1, Max=6
6-
2026-03-25T00:49:26+05:30 INFO Worker started worker_id=1
2+
2026-03-25T19:15:47+05:30 INFO Connected to Postgres
3+
2026-03-25T19:15:47+05:30 INFO Connected to Redis
4+
2026-03-25T19:15:47+05:30 INFO Starting Worker Pool (Min: 1, Max: 6)
5+
2026-03-25T19:15:47+05:30 INFO Code Runner Started on port :8080. Workers: Min=1, Max=6
6+
2026-03-25T19:15:47+05:30 INFO Worker started worker_id=1
7+
2026-03-25T19:16:02+05:30 INFO Processing job worker_id=1 job_id="d71ue6mmba62c9271dc0"
8+
2026-03-25T19:16:02+05:30 INFO Docker container created and started ContainerID="54e0ae2c9143050ed872722d9afb1993dea9073902ecb8a06c50fdbf3b631072"
9+
2026-03-25T19:16:02+05:30 INFO Job finished job_id="d71ue6mmba62c9271dc0" status="SUCCESS"
10+
2026-03-25T19:19:53+05:30 INFO Processing job worker_id=1 job_id="d71ug0emba62c9271dd0"
11+
2026-03-25T19:19:53+05:30 INFO Docker container created and started ContainerID="b3f20c80351e9a650946ec47baa06e86c4284d88d2809ad1166c901fc62d255b"
12+
2026-03-25T19:19:54+05:30 INFO Job finished job_id="d71ug0emba62c9271dd0" status="FAILURE"
13+
2026-03-25T19:22:09+05:30 INFO Processing job worker_id=1 job_id="d71uh2emba62c9271de0"
14+
2026-03-25T19:22:09+05:30 INFO Docker container created and started ContainerID="26d7eab9b7d0c544ee00a2ba66f6cc84e59799536612218e01db92fd18618c97"
15+
2026-03-25T19:22:09+05:30 INFO Job finished job_id="d71uh2emba62c9271de0" status="SUCCESS"
16+
2026-03-25T19:22:21+05:30 INFO Processing job worker_id=1 job_id="d71uh5emba62c9271df0"
17+
2026-03-25T19:22:21+05:30 INFO Docker container created and started ContainerID="b0cabb69ff9d3e3ae1ac150ca96661a9666574f21557539f1a9f516c163c2ad7"
18+
2026-03-25T19:22:21+05:30 INFO Job finished job_id="d71uh5emba62c9271df0" status="SUCCESS"
19+
2026-03-25T19:22:57+05:30 INFO Processing job worker_id=1 job_id="d71uheemba62c9271dg0"
20+
2026-03-25T19:22:57+05:30 INFO Docker container created and started ContainerID="07d30bd93365375c3119e99981f614b6aba4b3f98991e6ed2d617f730b4bea63"
21+
2026-03-25T19:22:57+05:30 INFO Job finished job_id="d71uheemba62c9271dg0" status="SUCCESS"
22+
2026-03-25T19:23:08+05:30 INFO Processing job worker_id=1 job_id="d71uhh6mba62c9271dh0"
23+
2026-03-25T19:23:08+05:30 INFO Docker container created and started ContainerID="5d9df4abfbb27c9fe2c68dca2f9ea5fd862b26bbdecd418648f5bfbd17eabcc4"
24+
2026-03-25T19:23:08+05:30 INFO Job finished job_id="d71uhh6mba62c9271dh0" status="SUCCESS"
25+
2026-03-25T19:23:25+05:30 INFO Processing job worker_id=1 job_id="d71uhlemba62c9271dig"
26+
2026-03-25T19:23:25+05:30 INFO Docker container created and started ContainerID="8f366a3677cc6a046a3d0f4731e75f56a13d7f7a0726218bdae23a85406f817c"
27+
2026-03-25T19:23:26+05:30 INFO Job finished job_id="d71uhlemba62c9271dig" status="SUCCESS"
28+
2026-03-25T19:30:45+05:30 INFO Processing job worker_id=1 job_id="d71ul3emba62c9271djg"
29+
2026-03-25T19:30:45+05:30 INFO Docker container created and started ContainerID="1c6acf936f8fb84234d12417416638355bd02a0d0fca54ebbb44d2505273a3e0"
30+
2026-03-25T19:30:45+05:30 INFO Job finished job_id="d71ul3emba62c9271djg" status="SUCCESS"
31+
2026-03-25T19:32:32+05:30 INFO Processing job worker_id=1 job_id="d71ulu6mba62c9271dkg"
32+
2026-03-25T19:32:32+05:30 INFO Docker container created and started ContainerID="083b5c87f6975dd1e43ee913a8105f9ea100497c9e3f588446bf5021a7a0ad32"
33+
2026-03-25T19:32:32+05:30 INFO Job finished job_id="d71ulu6mba62c9271dkg" status="SUCCESS"
34+
2026-03-25T19:43:37+05:30 INFO Processing job worker_id=1 job_id="d71ur4emba62c9271dlg"
35+
2026-03-25T19:43:37+05:30 INFO Docker container created and started ContainerID="26925b85bbb40cfbf346443914d3e0c26bf576e50e086496a29016e04390ac21"
36+
2026-03-25T19:43:38+05:30 INFO Job finished job_id="d71ur4emba62c9271dlg" status="SUCCESS"
37+
2026-03-25T19:45:51+05:30 INFO Processing job worker_id=1 job_id="d71us5umba62c9271dmg"
38+
2026-03-25T19:45:51+05:30 INFO Docker container created and started ContainerID="70c4772480d0a12a36dd9b28654d04767074700ce339f4aaa16b2add2a80d0fd"
39+
2026-03-25T19:45:51+05:30 INFO Job finished job_id="d71us5umba62c9271dmg" status="SUCCESS"
40+
2026-03-25T19:46:11+05:30 INFO Processing job worker_id=1 job_id="d71usaumba62c9271dng"
41+
2026-03-25T19:46:11+05:30 INFO Docker container created and started ContainerID="9c31453b4e8baab805766a32f3f45ab2475119f9cbc555088be44fb072c46760"
42+
2026-03-25T19:46:11+05:30 INFO Job finished job_id="d71usaumba62c9271dng" status="SUCCESS"
43+
2026-03-25T19:47:05+05:30 INFO Processing job worker_id=1 job_id="d71usoemba62c9271dp0"
44+
2026-03-25T19:47:05+05:30 INFO Docker container created and started ContainerID="dc8897140a85c3afac584738e848e24a2733e6fd643dae08db019602212e3180"
45+
2026-03-25T19:47:06+05:30 INFO Job finished job_id="d71usoemba62c9271dp0" status="SUCCESS"
46+
2026-03-25T19:47:15+05:30 INFO Processing job worker_id=1 job_id="d71usqumba62c9271dq0"
47+
2026-03-25T19:47:15+05:30 INFO Docker container created and started ContainerID="3cd05b9be83b69d4a376912c3a22b32ca8cba888fa50ef6532302b9797b6651c"
48+
2026-03-25T19:47:16+05:30 INFO Job finished job_id="d71usqumba62c9271dq0" status="FAILURE"
49+
2026-03-25T19:47:28+05:30 INFO Processing job worker_id=1 job_id="d71usu6mba62c9271dr0"
50+
2026-03-25T19:47:28+05:30 INFO Docker container created and started ContainerID="d6145e309218e206a296ed869dc2488c5f02f49253d4db5d1d00c86679e1a084"
51+
2026-03-25T19:47:28+05:30 INFO Job finished job_id="d71usu6mba62c9271dr0" status="FAILURE"
52+
2026-03-25T19:47:38+05:30 INFO Processing job worker_id=1 job_id="d71ut0mmba62c9271ds0"
53+
2026-03-25T19:47:38+05:30 INFO Docker container created and started ContainerID="d8a0ee0606678e5726f24fc6b0c518e96b0e535ed3ddce9051f152f8b3f68cf9"
54+
2026-03-25T19:47:38+05:30 INFO Job finished job_id="d71ut0mmba62c9271ds0" status="FAILURE"
55+
signal: killed

0 commit comments

Comments
 (0)