[web] Added execution time limit for we b app

This commit is contained in:
Sidi Liang 2024-11-05 22:40:01 +08:00
parent e6b88c9dec
commit 44e7077f46
No known key found for this signature in database
GPG Key ID: 9785F5EECFFA5311
2 changed files with 24 additions and 2 deletions

View File

@ -16,6 +16,7 @@
#include <stdexcept> #include <stdexcept>
#include <chrono> #include <chrono>
#include <vector> #include <vector>
#include <future>
namespace { namespace {
// Helper function implementations inside anonymous namespace // Helper function implementations inside anonymous namespace
@ -44,6 +45,7 @@ struct NasalContext {
std::unique_ptr<nasal::vm> vm_instance; std::unique_ptr<nasal::vm> vm_instance;
std::string last_result; std::string last_result;
std::string last_error; std::string last_error;
std::chrono::seconds timeout{5}; // Default 5 second timeout
NasalContext() { NasalContext() {
vm_instance = std::make_unique<nasal::vm>(); vm_instance = std::make_unique<nasal::vm>();
@ -71,6 +73,12 @@ void nasal_cleanup(void* context) {
delete static_cast<NasalContext*>(context); delete static_cast<NasalContext*>(context);
} }
// Add new function to set timeout
void nasal_set_timeout(void* context, int seconds) {
auto* ctx = static_cast<NasalContext*>(context);
ctx->timeout = std::chrono::seconds(seconds);
}
const char* nasal_eval(void* context, const char* code, int show_time) { const char* nasal_eval(void* context, const char* code, int show_time) {
using clk = std::chrono::high_resolution_clock; using clk = std::chrono::high_resolution_clock;
const auto den = clk::duration::period::den; const auto den = clk::duration::period::den;
@ -85,7 +93,7 @@ const char* nasal_eval(void* context, const char* code, int show_time) {
// Create a unique temporary file // Create a unique temporary file
char temp_filename[256]; char temp_filename[256];
snprintf(temp_filename, sizeof(temp_filename), "/tmp/nasal_eval_%d.nasal", getpid()); snprintf(temp_filename, sizeof(temp_filename), "/tmp/nasal_eval_%ld.nasal", std::time(nullptr));
int fd = mkstemp(temp_filename); int fd = mkstemp(temp_filename);
if (fd == -1) { if (fd == -1) {
throw std::runtime_error("Failed to create temporary file"); throw std::runtime_error("Failed to create temporary file");
@ -130,7 +138,20 @@ const char* nasal_eval(void* context, const char* code, int show_time) {
gen.compile(parse, ld, false, true).chkerr(); gen.compile(parse, ld, false, true).chkerr();
const auto start = show_time ? clk::now() : clk::time_point(); const auto start = show_time ? clk::now() : clk::time_point();
ctx->vm_instance->run(gen, ld, {});
// Create a future for the VM execution
auto future = std::async(std::launch::async, [&]() {
ctx->vm_instance->run(gen, ld, {});
});
// Wait for completion or timeout
auto status = future.wait_for(ctx->timeout);
if (status == std::future_status::timeout) {
std::remove(temp_filename);
throw std::runtime_error("Execution timed out after " +
std::to_string(ctx->timeout.count()) + " seconds");
}
const auto end = show_time ? clk::now() : clk::time_point(); const auto end = show_time ? clk::now() : clk::time_point();
std::cout.rdbuf(old_cout); std::cout.rdbuf(old_cout);

View File

@ -16,6 +16,7 @@ extern "C" {
// Main API functions // Main API functions
NASAL_EXPORT void* nasal_init(); NASAL_EXPORT void* nasal_init();
NASAL_EXPORT void nasal_cleanup(void* context); NASAL_EXPORT void nasal_cleanup(void* context);
NASAL_EXPORT void nasal_set_timeout(void* context, int seconds);
NASAL_EXPORT const char* nasal_eval(void* context, const char* code, int show_time); NASAL_EXPORT const char* nasal_eval(void* context, const char* code, int show_time);
NASAL_EXPORT const char* nasal_get_error(void* context); NASAL_EXPORT const char* nasal_get_error(void* context);