kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit d6d6f96ca06d5a009983bea88f1bb8872c6035f5
parent 94de8b27d21cb61fba6b03dda07f7840dedd388c
Author: Joris Vink <joris@coders.se>
Date:   Thu, 17 Apr 2014 10:49:48 +0200

Kore pgsql improvements.

Don't wait for a full event loop until we call the page handler
for a received pgsql result. This speeds up page loads using
KORE_PGSQL by quite a lot, especially on a non busy server.

Diffstat:
contrib/postgres/kore_pgsql.c | 14+++++++++++---
includes/contrib/postgres/kore_pgsql.h | 8--------
includes/http.h | 1+
src/http.c | 111+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
4 files changed, 75 insertions(+), 59 deletions(-)

diff --git a/contrib/postgres/kore_pgsql.c b/contrib/postgres/kore_pgsql.c @@ -132,7 +132,8 @@ kore_pgsql_handle(void *c, int err) i = conn->job->idx; req = conn->job->req; - kore_debug("kore_pgsql_handle(): %p (%d)", req, i); + kore_debug("kore_pgsql_handle: %p (%d) (%d)", + req, i, req->pgsql[i]->state); if (!PQconsumeInput(conn->db)) { req->pgsql[i]->state = KORE_PGSQL_STATE_ERROR; @@ -141,10 +142,12 @@ kore_pgsql_handle(void *c, int err) pgsql_read_result(req, i, conn); } - if (req->pgsql[i]->state == KORE_PGSQL_STATE_WAIT) + if (req->pgsql[i]->state == KORE_PGSQL_STATE_WAIT) { req->flags |= HTTP_REQUEST_SLEEPING; - else + } else { req->flags &= ~HTTP_REQUEST_SLEEPING; + http_process_request(req, 1); + } } void @@ -153,6 +156,9 @@ kore_pgsql_continue(struct http_request *req, int i) int fd; struct pgsql_conn *conn; + kore_debug("kore_pgsql_continue: %p->%p (%d) (%d)", + req->owner, req, i, req->pgsql[i]->state); + if (req->pgsql[i]->error) { kore_mem_free(req->pgsql[i]->error); req->pgsql[i]->error = NULL; @@ -180,6 +186,8 @@ kore_pgsql_continue(struct http_request *req, int i) fd = PQsocket(conn->db); kore_platform_disable_read(fd); + + http_process_request(req, 0); break; case KORE_PGSQL_STATE_ERROR: case KORE_PGSQL_STATE_RESULT: diff --git a/includes/contrib/postgres/kore_pgsql.h b/includes/contrib/postgres/kore_pgsql.h @@ -74,12 +74,4 @@ char *kore_pgsql_getvalue(struct kore_pgsql *, int, int); } \ } while (0); -#define KORE_PGSQL_EXEC(r, q, i) \ - do { \ - if (r->pgsql[i] == NULL) \ - kore_pgsql_query(r, q, i); \ - if (r->pgsql[i] == NULL) \ - return (KORE_RESULT_RETRY); \ - } while (0); - #endif diff --git a/includes/http.h b/includes/http.h @@ -161,6 +161,7 @@ void http_init(void); void http_process(void); time_t http_date_to_time(char *); void http_request_free(struct http_request *); +void http_process_request(struct http_request *, int); void http_response(struct http_request *, int, void *, u_int32_t); int http_request_header_get(struct http_request *, char *, char **); void http_response_header_add(struct http_request *, char *, char *); diff --git a/src/http.c b/src/http.c @@ -150,9 +150,7 @@ http_request_new(struct connection *c, struct spdy_stream *s, char *host, void http_process(void) { - struct kore_module_handle *hdlr; struct http_request *req, *next; - int r, (*cb)(struct http_request *); for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) { next = TAILQ_NEXT(req, list); @@ -170,57 +168,72 @@ http_process(void) if (!(req->flags & HTTP_REQUEST_COMPLETE)) continue; - if (req->hdlr != NULL) - hdlr = req->hdlr; - else - hdlr = kore_module_handler_find(req->host, req->path); + http_process_request(req, 0); + } +} - req->start = kore_time_ms(); - if (hdlr == NULL) { - r = http_generic_404(req); +void +http_process_request(struct http_request *req, int retry_only) +{ + struct kore_module_handle *hdlr; + int r, (*cb)(struct http_request *); + + kore_debug("http_process_request: %p->%p (%s)", + req->owner, req, req->path); + + if (req->flags & HTTP_REQUEST_DELETE) + return; + + if (req->hdlr != NULL) + hdlr = req->hdlr; + else + hdlr = kore_module_handler_find(req->host, req->path); + + req->start = kore_time_ms(); + if (hdlr == NULL) { + r = http_generic_404(req); + } else { + if (req->hdlr != hdlr && hdlr->auth != NULL) + r = kore_auth(req, hdlr->auth); + else + r = KORE_RESULT_OK; + + if (r == KORE_RESULT_OK) { + req->hdlr = hdlr; + cb = hdlr->addr; + worker->active_hdlr = hdlr; + r = cb(req); + worker->active_hdlr = NULL; } else { - if (req->hdlr != hdlr && hdlr->auth != NULL) - r = kore_auth(req, hdlr->auth); - else - r = KORE_RESULT_OK; - - if (r == KORE_RESULT_OK) { - req->hdlr = hdlr; - cb = hdlr->addr; - worker->active_hdlr = hdlr; - r = cb(req); - worker->active_hdlr = NULL; - } else { - /* - * Set r to KORE_RESULT_OK so we can properly - * flush the result from kore_auth(). - */ - r = KORE_RESULT_OK; - } - } - req->end = kore_time_ms(); - req->total += req->end - req->start; - - switch (r) { - case KORE_RESULT_OK: - r = net_send_flush(req->owner); - if (r == KORE_RESULT_ERROR) - kore_connection_disconnect(req->owner); - break; - case KORE_RESULT_ERROR: - kore_connection_disconnect(req->owner); - break; - case KORE_RESULT_RETRY: - break; + /* + * Set r to KORE_RESULT_OK so we can properly + * flush the result from kore_auth(). + */ + r = KORE_RESULT_OK; } + } + req->end = kore_time_ms(); + req->total += req->end - req->start; - if (r != KORE_RESULT_RETRY) { - kore_accesslog(req); + if (retry_only == 1 && r != KORE_RESULT_RETRY) + fatal("http_process_request: expected RETRY but got %d", r); - TAILQ_REMOVE(&http_requests, req, list); - http_request_free(req); - http_request_count--; - } + switch (r) { + case KORE_RESULT_OK: + r = net_send_flush(req->owner); + if (r == KORE_RESULT_ERROR) + kore_connection_disconnect(req->owner); + break; + case KORE_RESULT_ERROR: + kore_connection_disconnect(req->owner); + break; + case KORE_RESULT_RETRY: + break; + } + + if (r != KORE_RESULT_RETRY && !(req->flags & HTTP_REQUEST_DELETE)) { + kore_accesslog(req); + req->flags |= HTTP_REQUEST_DELETE; } } @@ -244,6 +257,8 @@ http_request_free(struct http_request *req) struct http_arg *q, *qnext; struct http_header *hdr, *next; + kore_debug("http_request_free: %p->%p", req->owner, req); + TAILQ_REMOVE(&(req->owner->http_requests), req, olist); for (hdr = TAILQ_FIRST(&(req->resp_headers)); hdr != NULL; hdr = next) {