예제 #1
0
/**
 * Start virtual judger
 */
void VirtualJudger::run() {
  log("Judger started");
  initHandShake();
  while (true) {
    socket->receiveFile(tmpfilename);
    Bott * bott = new Bott(tmpfilename);
    log((string) "Received a new task, problem: " + bott->Getvid() + ".");
    string result_filename = Bott::RESULTS_DIRECTORY +
        intToString(bott->Getrunid());
    if (bott->Gettype() == NEED_JUDGE) {
      // Currently for vjudge, only NEED_JUDGE is supported
      try {
        if (bott->Getsrc().length() < MIN_SOURCE_LENGTH) {
          // source code too short, may cause problem in remote OJ, such as PKU
          bott->Setout_filename(result_filename);
          generateSpecialResult(bott, "Compile Error");
          bott->Setce_info("Source code too short, minimum length: " +
              intToString(MIN_SOURCE_LENGTH));
          bott->save();
        } else {
          judge(bott, result_filename);
        }
      } catch (Exception & e) {
        // Exception occurs, set to Judge Error
        log((string) "Judge error! Reason: " + e.what());

        // reuse bott file
        bott->Setout_filename(result_filename);
        generateSpecialResult(bott, "Judge Error");
        bott->save();
      } catch (exception & e) {
        // Exception occurs, set to Judge Error
        log((string) "Judge error! Reason: " + e.what());

        // reuse bott file
        bott->Setout_filename(result_filename);
        generateSpecialResult(bott, "Judge Error");
        bott->save();
      }
      delete bott;
    } else {
      delete bott;
      throw Exception("Type not supported.");
    }
    socket->sendFile(result_filename);
  }
}
예제 #2
0
/**
 * Send a submit to remote, and store the judge result
 * @param bott      Submit info
 * @param filename  File store the result
 */
void VirtualJudger::judge(Bott * bott, string filename) {
  // login
  if (!logged_in) { // Not logged in, try login
    clearCookies();
    login();
    log("Logged in.");
    logged_in = true;
  }

  // submit
  int submit_status = submit(bott);
  if (submit_status == SUBMIT_OTHER_ERROR) {
    // first time fail, blame login status...
    log((string) "Submit error. Assume not logged in.");
    logged_in = false;
    clearCookies();
    login();
    log("Logged in.");
    logged_in = true;
    submit_status = submit(bott);
    if (submit_status == SUBMIT_OTHER_ERROR) {
      // second time fail, blame frequency
      if (info->GetOj() == "CodeChef") {
        // CodeChef's restriction is harsh... 30 seconds cool down required
        log("Submit error. Assume should sleep for a while, "
            "sleeping 30 seconds.");
        sleep(30);
      } else {
        log("Submit error. Assume should sleep for a while, sleeping " +
            intToString(VirtualJudger::SLEEP_INTERVAL) + " seconds.");
        sleep(VirtualJudger::SLEEP_INTERVAL);
      }
      submit_status = submit(bott);
    }
  } else if (submit_status == SUBMIT_INVALID_LANGUAGE &&
      (info->GetOj() == "SPOJ" || info->GetOj() == "CodeChef") &&
      convertLanguage(bott->Getlanguage()) == "41") {
    // Special HACK for Invalid Language on SPOJ/CodeChef, since they have two
    // C++ types and each covers a certain subset of problems
    log((string) "Try another C++ for SPOJ/CodeChef");
    bott->Setlanguage(1);
    submit_status = submit(bott);
  }
  if (submit_status != SUBMIT_OTHER_ERROR) log("Submitted.");

  // check submit status
  sleep(1); // sleep 1 second, just in case remote status table is not refreshed
  Bott * result;
  if (submit_status == SUBMIT_NORMAL) {
    // get status
    result = getStatus(bott);
    result->Setrunid(bott->Getrunid());
    if (result->Getresult() == "Compile Error") {
      try {
        result->Setce_info(getCEinfo(result));
      } catch (...) {
        log("Failed to get CE info, use empty one instead.");
        result->Setce_info("");
      }
    }
  } else {
    result = new Bott;
    result->Setrunid(bott->Getrunid());
    switch (submit_status) {
      case SUBMIT_SAME_CODE:
        generateSpecialResult(result, "Judge Error (Same Code)");
        break;
      case SUBMIT_INVALID_LANGUAGE:
        generateSpecialResult(result, "Judge Error (Invalid Language)");
        break;
      case SUBMIT_COMPILE_ERROR:
        generateSpecialResult(result, "Compile Error");
        break;
      default:
        log("Submit Error.");
        generateSpecialResult(result, "Judge Error");
    }
  }
  result->Setout_filename(filename);
  result->save();
  log("Done judging. Result: " + result->Getresult() + ", remote runid: " +
      result->Getremote_runid());
  delete result;
}