Skip to content

Commit

Permalink
add cpp submission
Browse files Browse the repository at this point in the history
  • Loading branch information
glasss13 committed Sep 30, 2024
1 parent 61a36f4 commit 945a77c
Show file tree
Hide file tree
Showing 27 changed files with 1,080 additions and 565 deletions.
8 changes: 5 additions & 3 deletions linter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ endif()

add_library(
NUTC-linter_lib OBJECT
src/firebase/fetching.cpp
src/pywrapper/runtime.cpp
src/fetching/fetching.cpp
src/runtime/cpp/cpp_runtime.cpp
src/runtime/python/python_runtime.cpp
src/spawning/spawning.cpp
src/crow/crow.cpp
# Utils
Expand All @@ -52,7 +53,8 @@ add_library(
add_library(
NUTC-linter-spawner_lib OBJECT
src/lint/lint.cpp
src/pywrapper/runtime.cpp
src/runtime/cpp/cpp_runtime.cpp
src/runtime/python/python_runtime.cpp
)

# --- Main executable libs ----
Expand Down
3 changes: 1 addition & 2 deletions linter/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,13 @@ tasks:
- test -f CMakeUserPresets.json
cmds:
- cmake --build {{.CMAKE_SUFFIX}} -j

run:
env:
NUTC_SPAWNER_BINARY_PATH: '{{if eq .RELEASE_BUILD "true"}}./build/NUTC-linter-spawner{{else}}./build/dev/NUTC-linter-spawner{{end}}'
vars:
LINTER_PATH: '{{if eq .RELEASE_BUILD "true"}}build/{{.NAME}}{{else}}build/dev/{{.NAME}}{{end}}'
cmds:
- task: built
- task: build
- ./{{ .LINTER_PATH }}

run-v:
Expand Down
8 changes: 6 additions & 2 deletions linter/src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
#define LOG_BACKUP_COUNT 5

#ifdef NUTC_LOCAL_DEV
# define FIREBASE_URL "http://firebase:9000/"
# define S3_URL "http://localhost:4566"
# define WEBSERVER_URL "http://localhost:16124"
#else
# define FIREBASE_URL "https://nutc-web-default-rtdb.firebaseio.com/"
# define S3_URL "https://nutc.s3.us-east-2.amazonaws.com"
# define WEBSERVER_URL "http://localhost:16124"
#endif

#define S3_BUCKET "nutc"

// Linting
#define LINT_AUTO_TIMEOUT_SECONDS 10

Expand Down
43 changes: 30 additions & 13 deletions linter/src/crow/crow.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "crow.hpp"

#include "firebase/fetching.hpp"
#include "fetching/fetching.hpp"
#include "logging.hpp"
#include "spawning/spawning.hpp"

Expand Down Expand Up @@ -41,14 +41,32 @@ get_server_thread()
log_e(main, "No algo_id provided");
return crow::response(400);
}
if (!req.url_params.get("language")) {
log_e(main, "No language provided");
return crow::response(400);
}
std::string uid = req.url_params.get("uid");
std::string algo_id = req.url_params.get("algo_id");
std::string language = req.url_params.get("language");

auto algo_code = nutc::client::get_algo(uid, algo_id);
spawning::AlgoLanguage algo_language;
if (language == "python") {
algo_language = spawning::AlgoLanguage::Python;
}
else if (language == "cpp") {
algo_language = spawning::AlgoLanguage::Cpp;
}
else {
log_e(main, "Invalid language provided: {}", language);
return crow::response(400);
}

auto algo_code = nutc::client::get_algo(algo_id);
if (!algo_code.has_value()) {
nutc::client::set_lint_failure(
nutc::client::set_lint_result(
uid,
algo_id,
false,
fmt::format(
"[linter] FAILURE - could not find algo {} for id {}\n",
algo_id,
Expand All @@ -66,17 +84,16 @@ get_server_thread()
return res;
}

client::LintingResultOption algo_status_code;
auto lint_res = spawner_manager.spawn_client(algo_code.value());
if (lint_res.success) {
nutc::client::set_lint_success(uid, algo_id, lint_res.message);
algo_status_code = client::LintingResultOption::SUCCESS;
}
else {
nutc::client::set_lint_failure(uid, algo_id, lint_res.message);
algo_status_code = client::LintingResultOption::FAILURE;
}
auto lint_res =
spawner_manager.spawn_client(algo_code.value(), algo_language);

nutc::client::set_lint_result(
uid, algo_id, lint_res.success, lint_res.message
);

client::LintingResultOption algo_status_code =
lint_res.success ? client::LintingResultOption::SUCCESS
: client::LintingResultOption::FAILURE;
crow::json::wvalue response({
{"linting_status", static_cast<int>(algo_status_code)}
});
Expand Down
168 changes: 168 additions & 0 deletions linter/src/fetching/fetching.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include "fetching.hpp"

#include "config.h"
#include "config.h.in"

#include <curl/curl.h>
#include <fmt/core.h>

#include <iostream>
#include <optional>
#include <regex>

namespace {
std::string
replaceDisallowedValues(const std::string& input)
{
std::regex newlinePattern("\\n");
std::string input2 = std::regex_replace(input, newlinePattern, "\\n");
std::regex disallowedPattern("[.$#\\[\\]]");

return std::regex_replace(input2, disallowedPattern, "");
}
} // namespace

namespace nutc {
namespace client {

void
set_lint_result(
const std::string& uid,
const std::string& algo_id,
bool succeeded,
const std::string& message
)
{
std::string endpoint =
fmt::format("{}/lint-result/{}/{}", WEBSERVER_URL, uid, algo_id);

SetLintBody body{succeeded, replaceDisallowedValues(message)};

database_request("POST", endpoint, glz::write_json(body), true);
}

static size_t
write_callback(void* contents, size_t size, size_t nmemb, void* userp)
{
auto* str = reinterpret_cast<std::string*>(userp);
auto* data = static_cast<char*>(contents);

str->append(data, size * nmemb);
return size * nmemb;
}

std::optional<std::string>
storage_request(const std::string& url)
{
std::string readBuffer;

CURL* curl = curl_easy_init();
if (curl) {
CURLcode res = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
if (res != CURLE_OK) {
return std::nullopt;
}
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
if (res != CURLE_OK) {
return std::nullopt;
}
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
if (res != CURLE_OK) {
return std::nullopt;
}

res = curl_easy_perform(curl);
if (res != CURLE_OK) {
return std::nullopt;
}
curl_easy_cleanup(curl);
}

return readBuffer;
}

std::optional<std::string>
get_algo(const std::string& algo_id)
{
std::string url = fmt::format("{}/{}/{}", S3_URL, S3_BUCKET, algo_id);
std::cout << "requesting file from [" << url << "]\n";
auto algo_file = storage_request(url);
return algo_file;
}

std::optional<glz::json_t>
database_request(
const std::string& method,
const std::string& url,
const std::string& data,
bool json_body
)
{
std::string readBuffer;

CURL* curl = curl_easy_init();
if (curl) {
CURLcode res = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
if (res != CURLE_OK) {
return std::nullopt;
}
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
if (res != CURLE_OK) {
return std::nullopt;
}
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
if (res != CURLE_OK) {
return std::nullopt;
}

if (json_body) {
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
if (res != CURLE_OK) {
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return std::nullopt;
}
}

if (method == "POST") {
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
if (res != CURLE_OK) {
curl_easy_cleanup(curl);
return std::nullopt;
}
}
else if (method == "PUT") {
res = curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
if (res != CURLE_OK) {
return std::nullopt;
}
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
if (res != CURLE_OK) {
return std::nullopt;
}
}
else if (method == "DELETE") {
res = curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
if (res != CURLE_OK) {
return std::nullopt;
}
}

res = curl_easy_perform(curl);
if (res != CURLE_OK) {
return std::nullopt;
}

curl_easy_cleanup(curl);
}
glz::json_t json{};
auto error = glz::read_json(json, readBuffer);
if (error) {
return std::nullopt;
}
return json;
}
} // namespace client
} // namespace nutc
45 changes: 45 additions & 0 deletions linter/src/fetching/fetching.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <curl/curl.h>
#include <glaze/glaze.hpp>

#include <optional>
#include <string>

namespace nutc {
namespace client {

struct SetLintBody {
bool success;
std::string message;
};

enum class LintingResultOption { UNKNOWN = -1, FAILURE, SUCCESS, PENDING };

std::optional<glz::json_t> database_request(
const std::string& method,
const std::string& url,
const std::string& data = "",
bool json_body = false
);

std::optional<std::string> storage_request(const std::string& url);

void set_lint_result(
const std::string& uid,
const std::string& algo_id,
bool succeeded,
const std::string& message
);

[[nodiscard]] std::optional<std::string> get_algo(const std::string& algo_id);

} // namespace client
} // namespace nutc

template <>
struct glz::meta<nutc::client::SetLintBody> {
using t = nutc::client::SetLintBody;
static constexpr auto value =
object("success", &t::success, "message", &t::message);
};
Loading

0 comments on commit 945a77c

Please sign in to comment.