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:
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) {