chore: assorted socket error handling

main
Sean McBride 4 years ago
parent 9ead528dfc
commit c1edca2a42

@ -12,7 +12,7 @@
#endif
#define LISTENER_THREAD_CORE_ID 0 /* Dedicated Listener Core */
#define LISTENER_THREAD_MAX_EPOLL_EVENTS 1024
#define LISTENER_THREAD_MAX_EPOLL_EVENTS 2048
#define RUNTIME_LOG_FILE "awesome.log"
#define RUNTIME_MAX_SANDBOX_REQUEST_COUNT (1 << 19) /* random! */
@ -83,9 +83,12 @@ runtime_is_worker()
static inline void
runtime_log_requests_responses()
{
debuglog("Requests: %u\n2XX: %u\n4XX: %u\n5XX: %u\nOutstanding Requests: %u\n", runtime_total_requests,
runtime_total_2XX_responses, runtime_total_4XX_responses, runtime_total_5XX_responses,
runtime_total_requests - runtime_total_2XX_responses - runtime_total_4XX_responses
- runtime_total_5XX_responses);
int64_t total_responses = runtime_total_2XX_responses + runtime_total_4XX_responses
+ runtime_total_5XX_responses;
int64_t outstanding_requests = (int64_t)runtime_total_requests - total_responses;
debuglog("Requests: %u (%ld outstanding)\n\tResponses: %ld\n\t\t2XX: %u\n\t\t4XX: %u\n\t\t5XX: %u\n",
runtime_total_requests, outstanding_requests, total_responses, runtime_total_2XX_responses,
runtime_total_4XX_responses, runtime_total_5XX_responses);
};
#endif

@ -73,14 +73,14 @@ runtime_initialize(void)
/**
* Rejects Requests as determined by admissions control
* @param socket_descriptor - the client we are rejecting
* @param client_socket - the client we are rejecting
*/
static inline void
listener_thread_reject(int socket_descriptor)
listener_thread_reject(int client_socket)
{
assert(socket_descriptor >= 0);
assert(client_socket >= 0);
int send_rc = send(socket_descriptor, HTTP_RESPONSE_504_SERVICE_UNAVAILABLE,
int send_rc = send(client_socket, HTTP_RESPONSE_504_SERVICE_UNAVAILABLE,
strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE), 0);
if (send_rc < 0) goto send_504_err;
@ -90,7 +90,7 @@ listener_thread_reject(int socket_descriptor)
#endif
close:
if (close(socket_descriptor) < 0) panic("Error closing client socket - %s", strerror(errno));
if (close(client_socket) < 0) panic("Error closing client socket - %s", strerror(errno));
return;
send_504_err:
debuglog("Error sending 504: %s", strerror(errno));
@ -116,31 +116,48 @@ listener_thread_main(void *dummy)
while (true) {
int request_count = epoll_wait(runtime_epoll_file_descriptor, epoll_events,
LISTENER_THREAD_MAX_EPOLL_EVENTS, -1);
if (request_count < 0) panic("epoll_wait: %s", strerror(errno));
if (request_count == 0) panic("Unexpectedly returned with epoll_wait timeout not set\n");
/* Capture Start Time to calculate absolute deadline */
uint64_t request_arrival_timestamp = __getcycles();
for (int i = 0; i < request_count; i++) {
if (epoll_events[i].events & EPOLLERR) {
perror("epoll_wait");
assert(false);
}
if (epoll_events[i].events & EPOLLERR) panic("epoll_wait: %s", strerror(errno));
/* Accept Client Request */
struct sockaddr_in client_address;
socklen_t client_length = sizeof(client_address);
struct module * module = (struct module *)epoll_events[i].data.ptr;
assert(module);
int es = module->socket_descriptor;
int socket_descriptor = accept(es, (struct sockaddr *)&client_address, &client_length);
if (socket_descriptor < 0) {
perror("accept");
assert(false);
}
int server_socket = module->socket_descriptor;
int client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_length);
if (client_socket < 0) panic("accept: %s", strerror(errno));
#ifdef LOG_TOTAL_REQS_RESPS
runtime_total_requests++;
runtime_log_requests_responses();
#endif
/* Peek to ensure the socket isn't empty. Return 400 and close if empty */
char peek_buffer[10];
int bytes = recv(client_socket, &peek_buffer, 9, MSG_PEEK);
if (bytes < 0) panic("Peek: %s\n", strerror(errno));
if (bytes == 0) {
send(client_socket, HTTP_RESPONSE_400_BAD_REQUEST,
strlen(HTTP_RESPONSE_400_BAD_REQUEST), 0);
if (close(client_socket) < 0) {
panic("Error closing client socket - %s", strerror(errno));
}
#ifdef LOG_TOTAL_REQS_RESPS
runtime_total_4XX_responses++;
debuglog("Listener Core rejected empty request\n");
runtime_log_requests_responses();
#endif
/* Advance in for loop to next socket */
continue;
};
/* Perform Admission Control */
uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5);
@ -153,13 +170,13 @@ listener_thread_main(void *dummy)
double admissions_estimate = (double)estimated_execution / module->relative_deadline;
if (runtime_admitted + admissions_estimate >= runtime_worker_threads_count) {
listener_thread_reject(socket_descriptor);
listener_thread_reject(client_socket);
continue;
}
/* Allocate a Sandbox Request */
struct sandbox_request *sandbox_request =
sandbox_request_allocate(module, module->name, socket_descriptor,
sandbox_request_allocate(module, module->name, client_socket,
(const struct sockaddr *)&client_address, request_arrival_timestamp,
admissions_estimate);

@ -74,14 +74,15 @@ static inline int
sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
{
assert(sandbox != NULL);
sandbox->request_response_data_length = 0;
assert(sandbox->module->max_request_size > 0);
assert(sandbox->request_response_data_length == 0);
#ifndef USE_HTTP_UVIO
int r = 0;
r = recv(sandbox->client_socket_descriptor, (sandbox->request_response_data), sandbox->module->max_request_size,
r = recv(sandbox->client_socket_descriptor, sandbox->request_response_data, sandbox->module->max_request_size,
0);
if (r == 0) debuglog("Socket %d returned 0 bytes\n", sandbox->client_socket_descriptor);
if (r < 0) {
debuglog("Error reading request data from client socket - %s", strerror(errno));
debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
return r;
}
while (r > 0) {
@ -94,7 +95,7 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
(sandbox->request_response_data + sandbox->request_response_data_length),
sandbox->module->max_request_size - sandbox->request_response_data_length, 0);
if (r < 0) {
debuglog("Error reading request data from client socket - %s", strerror(errno));
debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
return r;
}
}
@ -105,7 +106,7 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
worker_thread_process_io();
#endif
if (sandbox->request_response_data_length == 0) {
debuglog("request_response_data_length was unexpectedly 0");
debuglog("request_response_data_length was unexpectedly 0\n");
return 0;
}
sandbox->request_length = sandbox->request_response_data_length;

Loading…
Cancel
Save