Skip to content

Commit

Permalink
fix: error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
emil916 committed May 25, 2024
1 parent fdf75b4 commit 11d1484
Show file tree
Hide file tree
Showing 54 changed files with 604 additions and 172 deletions.
5 changes: 2 additions & 3 deletions runtime/include/http_router.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ http_router_init(http_router_t *router, size_t capacity)

static inline int
http_router_add_route(http_router_t *router, struct route_config *config, struct module *module,
struct module *pre_module)
struct module *module_proprocess)
{
assert(router != NULL);
assert(config != NULL);
Expand All @@ -41,8 +41,7 @@ http_router_add_route(http_router_t *router, struct route_config *config, struct

#ifdef EXECUTION_REGRESSION
/* Execution Regression setup */
assert(pre_module);
route.pre_module = pre_module;
route.module_proprocess = module_proprocess;
route.regr_model.bias = config->model_bias / 1000.0;
route.regr_model.scale = config->model_scale / 1000.0;
route.regr_model.num_of_param = config->model_num_of_param;
Expand Down
2 changes: 1 addition & 1 deletion runtime/include/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ struct route {
char *route;
struct http_route_total metrics;
struct module *module;
struct module *pre_module;
/* HTTP State */
uint32_t relative_deadline_us;
uint64_t relative_deadline; /* cycles */
char *response_content_type;
struct execution_histogram execution_histogram;
struct perf_window latency;
struct module *module_proprocess;
struct regression_model regr_model;
};
88 changes: 67 additions & 21 deletions runtime/include/route_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ enum route_config_member
{
route_config_member_route,
route_config_member_path,
route_config_member_path_premodule,
route_config_member_admissions_percentile,
route_config_member_relative_deadline_us,
route_config_member_path_preprocess,
route_config_member_model_bias,
route_config_member_model_scale,
route_config_member_model_num_of_param,
Expand All @@ -27,9 +27,9 @@ enum route_config_member
struct route_config {
char *route;
char *path;
char *path_premodule;
uint8_t admissions_percentile;
uint32_t relative_deadline_us;
char *path_preprocess;
uint32_t model_bias;
uint32_t model_scale;
uint32_t model_num_of_param;
Expand All @@ -54,14 +54,16 @@ route_config_print(struct route_config *config)
{
printf("[Route] Route: %s\n", config->route);
printf("[Route] Path: %s\n", config->path);
printf("[Route] Path of Preprocessing Module: %s\n", config->path_premodule);
printf("[Route] Admissions Percentile: %hhu\n", config->admissions_percentile);
printf("[Route] Relative Deadline (us): %u\n", config->relative_deadline_us);
printf("[Route] HTTP Response Content Type: %s\n", config->http_resp_content_type);
#ifdef EXECUTION_HISTOGRAM
printf("[Route] Path of Preprocessing Module: %s\n", config->path_preprocess);
printf("[Route] Model Bias: %u\n", config->model_bias);
printf("[Route] Model Scale: %u\n", config->model_scale);
printf("[Route] Model Num of Parameters: %u\n", config->model_num_of_param);
printf("[Route] Model Betas: [%u, %u]\n", config->model_beta1, config->model_beta2);
printf("[Route] HTTP Response Content Type: %s\n", config->http_resp_content_type);
#endif
}

/**
Expand All @@ -73,7 +75,7 @@ static inline int
route_config_validate(struct route_config *config, bool *did_set)
{
if (did_set[route_config_member_route] == false) {
fprintf(stderr, "path field is required\n");
fprintf(stderr, "route field is required\n");
return -1;
}

Expand All @@ -82,19 +84,14 @@ route_config_validate(struct route_config *config, bool *did_set)
return -1;
}

if (did_set[route_config_member_path_premodule] == false) {
fprintf(stderr, "path_premodule field is required\n");
return -1;
}

if (did_set[route_config_member_http_resp_content_type] == false) {
debuglog("http_resp_content_type not set, defaulting to text/plain\n");
config->http_resp_content_type = "text/plain";
}

if (scheduler != SCHEDULER_FIFO) {
if (scheduler != SCHEDULER_FIFO && scheduler != SCHEDULER_SJF) {
if (did_set[route_config_member_relative_deadline_us] == false) {
fprintf(stderr, "relative_deadline_us is required\n");
fprintf(stderr, "relative_deadline_us is required for the selected scheduler\n");
return -1;
}

Expand All @@ -103,20 +100,69 @@ route_config_validate(struct route_config *config, bool *did_set)
(uint32_t)RUNTIME_RELATIVE_DEADLINE_US_MAX, config->relative_deadline_us);
return -1;
}
}

#ifdef EXECUTION_HISTOGRAM
if (config->admissions_percentile > 99 || config->admissions_percentile < 50) {
fprintf(stderr, "admissions-percentile must be > 50 and <= 99 but was %u, defaulting to 70\n",
config->admissions_percentile);
config->admissions_percentile = 70;
}
#endif

#ifdef EXECUTION_REGRESSION
if (did_set[route_config_member_path_preprocess] == false) {
fprintf(stderr, "model path_preprocess field is required. Put zero if just default preprocessing\n");
return -1;
} else if (strcmp(config->path_preprocess, "0") == 0) {
config->path_preprocess = NULL;
}

if (did_set[route_config_member_model_bias] == false) {
fprintf(stderr, "model bias field is required\n");
return -1;
}

if (did_set[route_config_member_model_scale] == false) {
fprintf(stderr, "model scale field is required\n");
return -1;
}

if (did_set[route_config_member_model_num_of_param] == false) {
fprintf(stderr, "model num_of_param field is required\n");
return -1;
}

if (did_set[route_config_member_model_beta1] == false) {
fprintf(stderr, "model beta1 field is required\n");
return -1;
}

if (did_set[route_config_member_model_beta2] == false) {
fprintf(stderr, "model beta2 field is required. Put zero for just default preprocessing\n");
return -1;
}

#ifdef ADMISSIONS_CONTROL
if (did_set[route_config_member_admissions_percentile] == false) {
fprintf(stderr, "admissions_percentile is required\n");
if (config->model_num_of_param < 1) {
fprintf(stderr, "model num_of_param must be at least 1 (just default preprocessing)\n");
return -1;
} else if (config->model_num_of_param == 1) {
if (config->path_preprocess) {
fprintf(stderr, "model_num_of_param cannot be 1 when using tenant preprocessing\n");
return -1;
}

if (config->admissions_percentile > 99 || config->admissions_percentile < 50) {
fprintf(stderr, "admissions-percentile must be > 50 and <= 99 but was %u\n",
config->admissions_percentile);
if (config->model_beta2 != 0) {
fprintf(stderr, "model beta2 must be zero for just default preprocessing\n");
return -1;
}
} else {
/* For now we just support up to two params */
assert(config->model_num_of_param == 2);
if (config->path_preprocess == NULL) {
fprintf(stderr, "model_num_of_param cannot be more than 1 when just default preprocessing\n");
return -1;
}
#endif
}

#endif
return 0;
}
27 changes: 12 additions & 15 deletions runtime/include/route_config_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@
#include "json.h"
#include "route_config.h"

static const char *route_config_json_keys[route_config_member_len] = { "route",
"path",
"path_premodule",
"admissions-percentile",
"relative-deadline-us",
"model-bias",
"model-scale",
"model-num-of-param",
"model-beta1",
"model-beta2",
"http-resp-content-type" };
static const char *route_config_json_keys[route_config_member_len] = {
"route", "path", "admissions-percentile", "relative-deadline-us",
"path_preprocess", "model-bias", "model-scale", "model-num-of-param",
"model-beta1", "model-beta2", "http-resp-content-type"
};

static inline int
route_config_set_key_once(bool *did_set, enum route_config_member member)
Expand Down Expand Up @@ -66,11 +60,11 @@ route_config_parse(struct route_config *config, const char *json_buf, jsmntok_t
if (route_config_set_key_once(did_set, route_config_member_path) == -1) return -1;

config->path = strndup(json_buf + tokens[i].start, tokens[i].end - tokens[i].start);
} else if (strcmp(key, route_config_json_keys[route_config_member_path_premodule]) == 0) {
} else if (strcmp(key, route_config_json_keys[route_config_member_path_preprocess]) == 0) {
if (!is_nonempty_string(tokens[i], key)) return -1;
if (route_config_set_key_once(did_set, route_config_member_path_premodule) == -1) return -1;
if (route_config_set_key_once(did_set, route_config_member_path_preprocess) == -1) return -1;

config->path_premodule = strndup(json_buf + tokens[i].start, tokens[i].end - tokens[i].start);
config->path_preprocess = strndup(json_buf + tokens[i].start, tokens[i].end - tokens[i].start);
} else if (strcmp(key, route_config_json_keys[route_config_member_admissions_percentile]) == 0) {
if (!has_valid_type(tokens[i], key, JSMN_PRIMITIVE, json_buf)) return -1;
if (route_config_set_key_once(did_set, route_config_member_admissions_percentile) == -1)
Expand All @@ -89,6 +83,9 @@ route_config_parse(struct route_config *config, const char *json_buf, jsmntok_t
route_config_json_keys[route_config_member_relative_deadline_us],
&config->relative_deadline_us);
if (rc < 0) return -1;
} else if (strcmp(key, "expected-execution-us") == 0) {
if (!has_valid_type(tokens[i], key, JSMN_PRIMITIVE, json_buf)) return -1;
printf("The \"expected-execution-us\" field has been deprecated, so no need.\n");
} else if (strcmp(key, route_config_json_keys[route_config_member_model_bias]) == 0) {
if (!has_valid_type(tokens[i], key, JSMN_PRIMITIVE, json_buf)) return -1;
if (route_config_set_key_once(did_set, route_config_member_model_bias) == -1) return -1;
Expand Down Expand Up @@ -138,7 +135,7 @@ route_config_parse(struct route_config *config, const char *json_buf, jsmntok_t
tokens[i].end - tokens[i].start);
} else {
fprintf(stderr, "%s is not a valid key\n", key);
// return -1;
return -1;
}
}

Expand Down
6 changes: 4 additions & 2 deletions runtime/include/tenant_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ tenant_config_print(struct tenant_config *config)
{
printf("[Tenant] Name: %s\n", config->name);
printf("[Tenant] Path: %d\n", config->port);
printf("[Tenant] Replenishment Period (us): %u\n", config->replenishment_period_us);
printf("[Tenant] Max Budget (us): %u\n", config->max_budget_us);
if (scheduler == SCHEDULER_MTDS) {
printf("[Tenant] Replenishment Period (us): %u\n", config->replenishment_period_us);
printf("[Tenant] Max Budget (us): %u\n", config->max_budget_us);
}
printf("[Tenant] Routes Size: %zu\n", config->routes_len);
for (int i = 0; i < config->routes_len; i++) { route_config_print(&config->routes[i]); }
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/include/tenant_config_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ tenant_config_parse(struct tenant_config *config, const char *json_buf, jsmntok_

} else {
fprintf(stderr, "%s is not a valid key\n", key);
// return -1;
return -1;
}
}

Expand Down
33 changes: 18 additions & 15 deletions runtime/include/tenant_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,27 +115,30 @@ tenant_alloc(struct tenant_config *config)

assert(module != NULL);

struct module *pre_module = NULL;
struct module *module_proprocess = NULL;

#ifdef EXECUTION_REGRESSION
pre_module = module_database_find_by_path(&tenant->module_db, config->routes[i].path_premodule);
if (pre_module == NULL) {
/* Ownership of path moves here */
pre_module = module_alloc(config->routes[i].path_premodule, PREPROCESS_MODULE);
if (pre_module != NULL) {
module_database_add(&tenant->module_db, pre_module);
config->routes[i].path_premodule = NULL;
if (config->routes[i].path_preprocess) {
module_proprocess = module_database_find_by_path(&tenant->module_db,
config->routes[i].path_preprocess);
if (module_proprocess == NULL) {
/* Ownership of path moves here */
module_proprocess = module_alloc(config->routes[i].path_preprocess, PREPROCESS_MODULE);
if (module_proprocess != NULL) {
module_database_add(&tenant->module_db, module_proprocess);
config->routes[i].path_preprocess = NULL;
}
} else {
free(config->routes[i].path_preprocess);
config->routes[i].path_preprocess = NULL;
}
} else {
free(config->routes[i].path_premodule);
config->routes[i].path_premodule = NULL;
}

assert(pre_module != NULL);
assert(module_proprocess != NULL);
}
#endif

/* Ownership of config's route and http_resp_content_type move here */
int rc = http_router_add_route(&tenant->router, &config->routes[i], module, pre_module);
int rc = http_router_add_route(&tenant->router, &config->routes[i], module, module_proprocess);
if (unlikely(rc != 0)) {
panic("Tenant %s defined %lu routes, but router failed to grow beyond %lu\n", tenant->name,
config->routes_len, tenant->router.capacity);
Expand Down Expand Up @@ -181,4 +184,4 @@ get_next_timeout_of_tenant(uint64_t replenishment_period)
*/
int tenant_listen(struct tenant *tenant);
int listener_thread_register_tenant(struct tenant *tenant);
void tenant_preprocess(struct http_session *session);
void tenant_preprocess(struct http_session *session);
11 changes: 7 additions & 4 deletions runtime/src/tenant.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ tenant_listen(struct tenant *tenant)
void
tenant_preprocess(struct http_session *session)
{
/* No tenant preprocessing if the wasm module not provided by the tenant */
if (session->route->module_proprocess == NULL) goto done;
const uint64_t start = __getcycles();

/* Tenant Pre-processing - Extract other useful parameters */
struct sandbox *pre_sandbox = sandbox_alloc(session->route->pre_module, session, session->route,
struct sandbox *pre_sandbox = sandbox_alloc(session->route->module_proprocess, session, session->route,
session->tenant, 1);
if (sandbox_prepare_execution_environment(pre_sandbox)) panic("pre_sandbox environment setup failed");
pre_sandbox->state = SANDBOX_RUNNING_SYS;
Expand Down Expand Up @@ -62,9 +64,10 @@ tenant_preprocess(struct http_session *session)
sandbox_free_linear_memory(pre_sandbox);
sandbox_free(pre_sandbox);

session->did_preprocessing = true;

const uint64_t end = __getcycles();
session->preprocessing_duration = end - start;

done:
session->did_preprocessing = true;
}
#endif
#endif
2 changes: 0 additions & 2 deletions tests/CMSIS_5_NN/imageclassification/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
{
"name": "gwu",
"port": 10000,
"replenishment-period-us": 0,
"max-budget-us": 0,
"routes": [
{
"route": "/rand",
Expand Down
2 changes: 0 additions & 2 deletions tests/TinyEKF/by_iteration/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
{
"name": "gwu",
"port": 10000,
"replenishment-period-us": 0,
"max-budget-us": 0,
"routes": [
{
"route": "/ekf_first_iter",
Expand Down
2 changes: 0 additions & 2 deletions tests/TinyEKF/one_iteration/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
{
"name": "gwu",
"port": 10000,
"replenishment-period-us": 0,
"max-budget-us": 0,
"routes": [
{
"route": "/ekf",
Expand Down
Loading

0 comments on commit 11d1484

Please sign in to comment.