private void WaitUntilSandboxIsReady(Process sandbox) { var readyLineReadTask = sandbox.StandardOutput.ReadLineAsync(); if (readyLineReadTask.Wait(settings.MaintenanceTimeLimit) && readyLineReadTask.Result == "Ready") { return; } if (!sandbox.HasExited) { throw new SandboxException($"Песочница не ответила «Ready» через {settings.MaintenanceTimeLimit.TotalSeconds} секунд после запуска, убиваю её"); } if (sandbox.ExitCode != 0) { log.Warn($"Песочница не ответила «Ready», а вышла с кодом {sandbox.ExitCode}"); var stderrReader = new AsyncReader(sandbox.StandardError, settings.OutputLimit + 1); var stderrData = stderrReader.GetDataAsync().Result; log.Warn($"Вывод песочницы в stderr:\n{stderrData}"); var result = GetResultForNonZeroExitCode(stderrData, sandbox.ExitCode); throw new SandboxException(result.Error); } throw new SandboxException("Sandbox unexpectedly exited before respond"); }
private void RunSolutionAndWaitUntilSandboxExit(Process sandbox, out string sandboxOutput, out string sandboxError) { sandbox.Refresh(); var startUsedMemory = sandbox.WorkingSet64; var startUsedTime = sandbox.TotalProcessorTime; var startTime = DateTime.Now; sandbox.StandardInput.WriteLine("Run"); sandbox.StandardInput.Flush(); sandbox.StandardInput.WriteLineAsync(submission.Input); var stderrReader = new AsyncReader(sandbox.StandardError, settings.OutputLimit + 1); var stdoutReader = new AsyncReader(sandbox.StandardOutput, settings.OutputLimit + 1); while (!sandbox.HasExited && !CheckIsTimeLimitExceeded(sandbox, startTime, startUsedTime) && !CheckIsMemoryLimitExceeded(sandbox, startUsedMemory) && !CheckIsOutputLimit(stdoutReader) && !CheckIsOutputLimit(stderrReader)) { } if (!hasTimeLimit && !hasMemoryLimit && !hasOutputLimit) { /* Read all data to the end of streams */ sandboxError = stderrReader.GetDataAsync().Result; sandboxOutput = stdoutReader.GetDataAsync().Result; hasOutputLimit = CheckIsOutputLimit(stdoutReader); hasOutputLimit = CheckIsOutputLimit(stderrReader); } else { sandboxError = ""; sandboxOutput = ""; } }