cs136 / seashell

Seashell is an online environment for editing, running, and submitting C programming assignments.
GNU General Public License v3.0
38 stars 19 forks source link

Display student's program output if timeout or killed. Show reminders… #707

Closed yc2lee closed 7 years ago

yc2lee commented 7 years ago

This pull request fixes the problem where if the student's program times out or is killed, stdout and stderr output up until that point are NOT displayed to the student. With this pull request, when a timeout or kill action occurs, stdout and stderr contents will be displayed, up to a certain length ('max-output-bytes-to-keep setting, set to 10,000 bytes).

The problem was caused by 2 different things:

  1. There wasn't any backend code at all to send output to the front end when timeouts or kill occurs. Adding the code is pretty simple (similar to the "pass" and "fail" cases).
  2. If students have an infinite loop that prints output, it will make the internal pipes consume a ton of memory. This causes the call-with-limits resource limits to trigger in dispatch.rkt. It turns out that in Racket, threads inside call-with-limits's thunk are subject to the resource limits, but they do NOT trigger the exn:fail:resource? exception when exceeding those limits. To fix this problem, I make the internal pipes store at most 'subprocess-buffer-size MBs of data (a config setting set to 20MB). Any output from the student's program beyond this 20MB is thrown away (we won't send more than 10,000 bytes to the frontend anyways).

This pull request also has some frontend Javascript code that will print out the message "Still testing. N tests left...." every 8 seconds. I added this because it might be confusing for students to stare at a blank console for 30 seconds waiting for a timeout. I can remove this code if you want. We can add a proper progress-bar-like thing later; this is a quick hack in the meantime.

yc2lee commented 7 years ago

Are you sure because my first-n-bytes also appends a message iff bytes are deleted. If I used (read-bytes ...) I still need to compare the length or something similar to check if I should append the "bytes were deleted" message.

yc2lee commented 7 years ago

Should I rename the function and/or implement it using (read-bytes ...) instead?

e45lee commented 7 years ago

So the thing is that you don't want to extract everything using (port->bytes). You probably want (first-n-bytes) to use read-bytes to get the first n bytes, and then use byte-ready? to test if there are remaining bytes.

yc2lee commented 7 years ago

Oh okay I see

yc2lee commented 7 years ago

okay I think i fixed it!