Decode request maps directly into Wasm workspaces
This commit is contained in:
+66
-17
@@ -1266,6 +1266,58 @@ private:
|
||||
std::vector<String> hostcall_operation_names;
|
||||
};
|
||||
|
||||
// The request envelope keeps app scratch state separate from transport fields.
|
||||
// Maps use UCEB2 directly so the guest can populate Request StringMaps without
|
||||
// constructing and then copying a duplicate DValue subtree.
|
||||
static void wasm_request_envelope_append(String& envelope, const String& value)
|
||||
{
|
||||
u64 size = value.size();
|
||||
while(size >= 0x80)
|
||||
{
|
||||
envelope.push_back((char)((size & 0x7f) | 0x80));
|
||||
size >>= 7;
|
||||
}
|
||||
envelope.push_back((char)size);
|
||||
envelope.append(value.data(), value.size());
|
||||
}
|
||||
|
||||
static String wasm_encode_request_envelope(const Request& request, const String& entry_unit, const String& handler)
|
||||
{
|
||||
String envelope = "UCER";
|
||||
envelope.push_back(1);
|
||||
envelope.push_back(12);
|
||||
wasm_request_envelope_append(envelope, ucb_encode(request.call));
|
||||
wasm_request_envelope_append(envelope, ucb_encode_flat_string_map(request.params));
|
||||
wasm_request_envelope_append(envelope, ucb_encode_flat_string_map(request.get));
|
||||
wasm_request_envelope_append(envelope, ucb_encode_flat_string_map(request.post));
|
||||
wasm_request_envelope_append(envelope, ucb_encode_flat_string_map(request.cookies));
|
||||
wasm_request_envelope_append(envelope, ucb_encode_flat_string_map(request.session));
|
||||
wasm_request_envelope_append(envelope, request.session_id);
|
||||
wasm_request_envelope_append(envelope, request.session_name);
|
||||
wasm_request_envelope_append(envelope, request.session_loaded_hash);
|
||||
wasm_request_envelope_append(envelope, entry_unit);
|
||||
wasm_request_envelope_append(envelope, request.in);
|
||||
String websocket;
|
||||
if(handler == "websocket")
|
||||
{
|
||||
DValue ws;
|
||||
ws["connection_id"] = request.resources.websocket_connection_id;
|
||||
ws["scope"] = request.resources.websocket_scope;
|
||||
ws["opcode"] = (f64)request.resources.websocket_opcode;
|
||||
ws["binary"].set_bool(request.resources.websocket_is_binary);
|
||||
for(auto& id : request.resources.websocket_scope_connection_ids)
|
||||
{
|
||||
DValue value;
|
||||
value = id;
|
||||
ws["connections"].push(value);
|
||||
}
|
||||
ws["connection_state"] = request.connection;
|
||||
websocket = ucb_encode(ws);
|
||||
}
|
||||
wasm_request_envelope_append(envelope, websocket);
|
||||
return(envelope);
|
||||
}
|
||||
|
||||
// ---- workspace (per request) ----------------------------------------------
|
||||
|
||||
class WasmWorkspace : public WasmRequestProfile
|
||||
@@ -1524,7 +1576,7 @@ public:
|
||||
return("");
|
||||
}
|
||||
|
||||
String apply_context(const DValue& context_tree)
|
||||
String apply_context(const Request& request, const String& entry_unit, const String& handler)
|
||||
{
|
||||
auto phase_start = std::chrono::steady_clock::now();
|
||||
auto phase_us = [&]() -> u64 {
|
||||
@@ -1533,7 +1585,7 @@ public:
|
||||
phase_start = now;
|
||||
return(elapsed);
|
||||
};
|
||||
String encoded = ucb_encode(context_tree);
|
||||
String encoded = wasm_encode_request_envelope(request, entry_unit, handler);
|
||||
server_config_bytes = worker.server_config_encoded.size();
|
||||
context_bytes = server_config_bytes + encoded.size();
|
||||
context_encode_us = phase_us();
|
||||
@@ -3787,15 +3839,15 @@ inline String wasm_worker_prepare(WasmWorker& worker)
|
||||
|
||||
// ---- public entry: one request through one workspace -----------------------
|
||||
|
||||
inline WasmResponse wasm_worker_serve(WasmWorker& worker, const DValue& context_tree, const String& entry_source_path,
|
||||
const String& handler = "render", const Request* request = 0)
|
||||
inline WasmResponse wasm_worker_serve(WasmWorker& worker, const Request& request, const String& entry_source_path,
|
||||
const String& handler = "render")
|
||||
{
|
||||
WasmResponse response;
|
||||
f64 serve_started = time_precise();
|
||||
auto workspace_start = std::chrono::steady_clock::now();
|
||||
f64 cpu_started = wasm_thread_cpu_time();
|
||||
struct rusage thread_runtime_start = {};
|
||||
bool thread_runtime_profiled = request && worker.cfg.profile_thread_runtime && getrusage(RUSAGE_THREAD, &thread_runtime_start) == 0;
|
||||
bool thread_runtime_profiled = worker.cfg.profile_thread_runtime && getrusage(RUSAGE_THREAD, &thread_runtime_start) == 0;
|
||||
int thread_cpu_start = thread_runtime_profiled ? sched_getcpu() : -1;
|
||||
WasmWorkspace workspace(worker);
|
||||
f64 setup_cpu_finished = wasm_thread_cpu_time();
|
||||
@@ -3803,17 +3855,14 @@ inline WasmResponse wasm_worker_serve(WasmWorker& worker, const DValue& context_
|
||||
std::chrono::steady_clock::now() - workspace_start).count();
|
||||
workspace.workspace_setup_cpu_us = cpu_started > 0 && setup_cpu_finished > cpu_started ?
|
||||
(u64)((setup_cpu_finished - cpu_started) * 1000000.0) : 0;
|
||||
if(request)
|
||||
{
|
||||
workspace.set_perf_snapshot(my_pid, (u64)parent_pid, request->server ? request->server->request_count : 0,
|
||||
request->stats.time_init, request->stats.time_params, request->stats.time_input, request->stats.time_start,
|
||||
serve_started, cpu_started);
|
||||
workspace.request_perf.thread_runtime_start = thread_runtime_start;
|
||||
workspace.request_perf.thread_cpu_start = thread_cpu_start;
|
||||
workspace.request_perf.thread_runtime_profiled = thread_runtime_profiled;
|
||||
if(request->stats.time_start > 0 && serve_started > request->stats.time_start)
|
||||
workspace.dispatch_us = (u64)((serve_started - request->stats.time_start) * 1000000.0);
|
||||
}
|
||||
workspace.set_perf_snapshot(my_pid, (u64)parent_pid, request.server ? request.server->request_count : 0,
|
||||
request.stats.time_init, request.stats.time_params, request.stats.time_input, request.stats.time_start,
|
||||
serve_started, cpu_started);
|
||||
workspace.request_perf.thread_runtime_start = thread_runtime_start;
|
||||
workspace.request_perf.thread_cpu_start = thread_cpu_start;
|
||||
workspace.request_perf.thread_runtime_profiled = thread_runtime_profiled;
|
||||
if(request.stats.time_start > 0 && serve_started > request.stats.time_start)
|
||||
workspace.dispatch_us = (u64)((serve_started - request.stats.time_start) * 1000000.0);
|
||||
auto birth_start = std::chrono::steady_clock::now();
|
||||
f64 birth_cpu_start = wasm_thread_cpu_time();
|
||||
String error = workspace.birth();
|
||||
@@ -3826,7 +3875,7 @@ inline WasmResponse wasm_worker_serve(WasmWorker& worker, const DValue& context_
|
||||
{
|
||||
auto context_start = std::chrono::steady_clock::now();
|
||||
f64 context_cpu_start = wasm_thread_cpu_time();
|
||||
error = workspace.apply_context(context_tree);
|
||||
error = workspace.apply_context(request, entry_source_path, handler);
|
||||
f64 context_cpu_finished = wasm_thread_cpu_time();
|
||||
workspace.context_apply_us = (u64)std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::steady_clock::now() - context_start).count();
|
||||
|
||||
Reference in New Issue
Block a user